Home avatar

分享Python/Java/Go/Rust编程技术,AI创作爱好者

【安全贴士】私钥分片和管道口令读取

通过一个私钥分片和管道口令读取的脚步来自动签发数字证书

私钥文件分片.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
# 私钥文件分片存储
# @author XiongNeng
# @since 2019/05/06

WORK_DIR="/home/ca/work"
key1=certs/B1BF8FF1C636C6FA.crt
key2=csr/server0.csr
key3=private/ca0.key
KEY_FILE="ca3.key"
SPLIT_PREFIX="ca3_"

split_key() {
	cd $WORK_DIR
	/bin/split $KEY_FILE -l 10 $SPLIT_PREFIX
	mv "${SPLIT_PREFIX}aa" $key1
	mv "${SPLIT_PREFIX}ab" $key2
	mv "${SPLIT_PREFIX}ac" $key3
}

merge_key() {
	cd $WORK_DIR
	cakey="/tmp/$(/bin/date +%s).key"
	/bin/cat $key1 $key2 $key3 > $cakey
	echo $cakey
}

if [[ "$#" < 1 || ("$1" != "split" && "$1" != "merge") ]]; then
    echo "Usage: ./split.sh split|merge"
    exit 1
fi

if [[ "$1" == "split" ]]; then
    split_key
else
    merge_key
fi

管道文件读取口令密钥.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/bin/bash
# 通过管道文件输入私钥密码,签发数字证书
# @author XiongNeng
# @since 2019/05/06

CRT="ca3.crt"
CSR="csr/server.csr"
OUT_CERT="certs/server3.crt"
WORK_DIR="/home/ca/work"
KEY_PASSWORD_FILE="${WORK_DIR}/keypass"
PROCESS_ACCOUNT="ca"

sign() {
	LOG_FILE="${WORK_DIR}/$(/bin/date +%s).log"
	# su - $PROCESS_ACCOUNT
	cd $WORK_DIR

	# 通过系统命令调用外部程序获取私钥密码
	KEY_PASSOWRD="123456"

	if [ "$KEY_PASSOWRD" = "" ];then
		echo "ERROR: cert key password is empty."
		return 1
	fi

	#创建管道文件
	# su -s /bin/sh $PROCESS_ACCOUNT -c "mkfifo ${WORK_DIR}/keypass"
	if [[ -p "${WORK_DIR}/keypass" ]]; then
	    echo "keypass pipe file exists, I will delete it"
	    rm -f "${WORK_DIR}/keypass"
	fi
	mkfifo ${WORK_DIR}/keypass
	if [ $? -ne 0 ];then
		echo "ERROR: mkfifo keypass failed."
		return 1
	fi

	#设置管道文件权限
	chown $PROCESS_ACCOUNT:$PROCESS_ACCOUNT ${WORK_DIR}/keypass
	if [ $? -ne 0 ]; then
		echo "ERROR: chown keypass failed."
		return 1
	fi

	chmod 600 ${WORK_DIR}/keypass
	if [ $? -ne 0 ]; then
		echo "ERROR: chmod keypass failed."
		return 1
	fi

	#以$PROCESS_ACCOUNT身份启动证书签名命令
	/bin/openssl x509 -req -days 3650 -CAcreateserial -CA $CRT -CAkey $1 -passin file:$KEY_PASSWORD_FILE -in $CSR -out $OUT_CERT &>${LOG_FILE} &

	#将密码写入管道文件
	echo "INFO: start echo key_password."
	echo $KEY_PASSOWRD >> ${WORK_DIR}/keypass 
	sleep 0.1

	#检查证书签发命令是否执行成功
	timeout=3
	num=0
	while [ $num -lt $timeout ]; do
		grep ":error:" ${LOG_FILE}
		if [ $? -eq 0 ]; then
			echo "Error: sign cert failed."
			return 1
		fi
		echo "sleep 1 seconds"
		sleep 1
		num=`expr $num + 1`
	done
	
	cat ${LOG_FILE}

	if [ $num -eq $timeout ]; then
		echo "Success: good luck."
	fi
	rm -f "${WORK_DIR}/keypass" ${LOG_FILE} $1
}

if [[ "$#" < 1 ]]; then
    echo "Usage: ./sign.sh /tmp/ca.key"
    exit 1
fi

sign $1

【安全贴士】一键生成证书脚本

这里演示如何通过命令行一键生成自签名CA证书,以及对于已有的证书生成服务证书库和信任证书库。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
#!/usr/bin/env bash
####################################################
# 一键生成证书库server.p12和信任证书库root.p12
# 证书库由openssl命令生成,信任证书库由keytool工具生成。
# ./x509.sh
####################################################

# 定义变量
export CA_WORK_DIR=`pwd`
export config="${CA_WORK_DIR}/myopenssl.cnf"
export root_key_password=123456
export root_p12_password=123456
export middle_key_password=123456
export server_key_password=123456
export server_p12_password=123456
export sign_key_password=123456
export cn="test20201229"
export days=3550

# 生成必要的文件
[[ -d private ]] || mkdir private
[[ -d csr ]] || mkdir csr
[[ -d certs ]] || mkdir certs 
# 初始化索引文件
[[ -f index.txt ]] || touch index.txt
# 吊销序列号文件
[[ -f index.txt ]] || touch crlnumber

# 初始化openssl配置
grep "v3_server_client" $config &>/dev/null
if [[ "$?" != "0" ]]; then
    cp /etc/pki/tls/openssl.cnf $config
    cat <<EOF >>$config

[ v3_rootca ]
basicConstraints = critical, CA:true
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = critical, cRLSign, digitalSignature, keyCertSign
crlDistributionPoints=URI:https://example.com/rootca.crl

[ v3_middleca ]
basicConstraints = critical, CA:true
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = critical, cRLSign, digitalSignature, keyCertSign
crlDistributionPoints=URI:https://example.com/middleca.crl

[ v3_server_client ]
basicConstraints        = critical, CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer:always
keyUsage                = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage        = critical, serverAuth, clientAuth
crlDistributionPoints   = URI:https://example.com/server.crl

[ v3_sign ]
basicConstraints        = critical, CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer:always
keyUsage                = critical, digitalSignature
extendedKeyUsage        = critical, codeSigning
EOF
fi

# 生成CA根证书
if [[ ! -f private/root.key ]]; then
    (umask 077; openssl genrsa -aes256 -passout pass:${root_key_password} -out private/root.key 3072)
    openssl req -x509 -days 3650 -sha256 -extensions v3_rootca -key private/root.key -passin pass:${root_key_password} \
        -out root.crt -subj "/C=CN/ST=SX/L=XA/O=xncoding/OU=GTS/CN=root.xncoding.com/emailAddress=root@xncoding.com" \
        -config ${config}
    keytool -import -noprompt -trustcacerts -alias rootca -file root.crt -keystore root.p12 \
        -storetype PKCS12 -storepass ${root_p12_password}
fi

# 生成二级CA证书
if [[ ! -f private/middle.key ]]; then
    (umask 077; openssl genrsa -aes256 -passout pass:${middle_key_password} -out private/middle.key 3072)
    openssl req -new -extensions v3_middleca -key private/middle.key -passin pass:${middle_key_password} \
        -out csr/middle.csr -subj "/C=CN/ST=SX/L=XA/O=xncoding/OU=DC/CN=middle/emailAddress=middle@xncoding.com" \
        -config ${config}
    openssl x509 -req -extensions v3_middleca -days ${days} -sha256 -CAcreateserial -CA root.crt \
        -CAkey private/root.key -passin pass:${root_key_password} -in csr/middle.csr -out middle.crt \
        -extfile ${config}
fi

# 签发服务证书
(umask 077; openssl genrsa -aes256 -passout pass:${server_key_password} -out private/server.key 3072)
openssl req -new -extensions v3_server_client -key private/server.key -passin pass:${server_key_password} \
    -out csr/server.csr -subj "/C=CN/ST=SX/L=XA/O=xncoding/OU=DC/CN=${cn}/emailAddress=${cn}@xncoding.com" \
    -config ${config}
openssl x509 -req -extensions v3_server_client -days ${days} -sha256 -CAcreateserial -CA middle.crt \
    -CAkey private/middle.key -passin pass:${middle_key_password} -in csr/server.csr -out certs/server.crt \
    -extfile ${config}

# 导出服务证书为PKCS12的证书链
[[ -f cachain.crt ]] || cat middle.crt root.crt > cachain.crt
openssl pkcs12 -export -inkey private/server.key -passin pass:${server_key_password} \
    -in certs/server.crt -chain -CAfile cachain.crt -out certs/server.p12 -password pass:${server_p12_password} \
    -keypbe aes-256-cbc -certpbe aes-256-cbc

# 最后删除临时文件
rm -f csr/server.csr csr/middle.csr

# 查看证书库信息
# openssl pkcs12 -info -in certs/server.p12 -nodes -passin pass:${server_p12_password}