我想创建一个 pkcs12 格式的证书存储文件,用于在 thunderbird 中进行 s/mime 签名和加密。我已经运行了一个邮件和 Web 服务器,该服务器使用由我创建的 CA 证书签名的证书。我想用同一个 CA 为邮件用户的证书签名。
我松散地跟随本指南但调整了我的步骤以适应我的设置。
CA 证书采用 PEM 格式。
我像这样创建 p12 证书存储
touch ./tmp.pwd && chmod 600 ./tmp.pwd
vim ./tmp.pwd # enter password
mkdir reqs && mkdir certs && mkdir Pkeys
CLIENT_MAIL="[email protected]"
CN="My Name"
BASE_FILE_NAME="mail_cert"
# generate request and private key
# NOTE 1*
openssl req -new -passout: file:./tmp.pwd -keyout "Pkeys/${BASE_FILE_NAME}-key.pem" -out "reqs/${BASE_FILE_NAME}.pem" -subj "/O=${O}/CN=${CN}/emailAddress=${CLIENT_MAIL}" -extensions smime -config ./openssl.cnf
# check request
openssl req -noout -text -in "reqs/${BASE_FILE_NAME}.pem"
# issue the certificate
openssl ca -in "reqs/${BASE_FILE_NAME}.pem" -days 3650 -batch -out "certs/${BASE_FILE_NAME}-cert.pem" -extensions smime -config ./openssl.cnf
# verify
openssl verify -CAfile "CA.pem" "certs/${BASE_FILE_NAME}-cert.pem"
# NOTE 2*
openssl x509 -noout -text -in "certs/${BASE_FILE_NAME}-cert.pem"
# build certificate chain
openssl x509 -in CA.pem -inform PEM -out tmp-root.x509
openssl x509 -in "certs/${BASE_FILE_NAME}-cert.pem" -inform PEM -out tmp-cert.x509
cat "tmp-cert.x509" "tmp-root.x509" > "certs/${BASE_FILE_NAME}-cert-chain.pem"
rm tmp-cert.x509 tmp-root.x509
# make pkcs12 container
# openssl can't open the same file twice for password
cp tmp.pwd tmp2.pwd
openssl pkcs12 -passin file:./tmp.pwd -passout file:tmp2.pwd -export -in "certs/${BASE_FILE_NAME}-cert-chain.pem" -inkey "Pkeys/${BASE_FILE_NAME}-key.pem" -CAfile CA.pem -out "certs/${BASE_FILE_NAME}-cert.p12"
rm ./tmp2.pwd
# check
# NOTE 3*
openssl pkcs12 -passin file:.tmp.pwd -info -in "certs/${BASE_FILE_NAME}-cert.p12" -noout
rm ./tmp.pwd ./tmp2.pwd
问题是我可以在 thunderbird 中顺利导入证书,甚至可以选择它进行签名和加密。但当我实际尝试发送签名邮件时,我收到此错误:
邮件发送失败。
您指定该邮件应进行数字签名,但应用程序无法找到您在“邮件和新闻组帐户设置”中指定的签名证书,或者证书已过期。
我注意到,当我在 thunderbird 中查看证书时,它只显示证书本身,而我相信它应该在顶部的单独选项卡中显示 CA 证书,就像 firefox 对 Web 证书所做的那样。
注 1
openssl.cnf 文件如下所示
[ ca ]
default_ca = CA_redacted
[ none ]
# Empty section
[ CA_redacted ]
dir = .
certs = $dir/certs
crl_dir = $dir/crls
database = $dir/db/index.txt
new_certs_dir = $certs
certificate = $dir/CA.pem
serial = $dir/db/serial
crl = $dir/crls/crl.pem
private_key = $dir/CAkey/CA_key.pem
RANDFILE = $dir/CAkey/.rand
copy_extensions = copy
x509_extensions = cert_ext
default_days = 3650
default_crl_days = 365
default_md = sha512
policy = policy
# policy for requests to be valid
[ policy ]
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# These extensions are copied to the issued certs when signing it.
[ cert_ext ]
basicConstraints = critical,CA:FALSE
authorityKeyIdentifier = keyid,issuer:always
subjectKeyIdentifier = hash
issuerAltName = issuer:copy
authorityInfoAccess = caIssuers;URI:http://redacted/CA.der
crlDistributionPoints = URI:http://redacted/crl.pem
# Extensions for the CA itself.
[ CA_cert_ext ]
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign, digitalSignature, dataEncipherment, keyEncipherment, digitalSignature
extendedKeyUsage = serverAuth,clientAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = none
[ req ]
default_bits = 8192
distinguished_name = req_dn
x509_extensions = CA_cert_ext
req_extensions = v3_req
# this section is not used for mail.
[ v3_req ]
# [.. snip]
[ req_dn ]
0.organizationName = Organization Name (eg. company)
0.organizationName_default = redacted
organizationalUnitName = Organization Unit Name
commonName = Common Name
commonName_default = CHANGEME
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
# This section is used to add extensions when signing certificates used for email protection
[ smime ]
basicConstraints = critical, CA:FALSE
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = emailProtection
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer
subjectAltName = email:copy
笔记2
创建的邮件证书如下所示
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 37 (0x25)
Signature Algorithm: sha512WithRSAEncryption
Issuer: O = [redacted], CN = CA Server
Validity
Not Before: May 13 00:14:38 2023 GMT
Not After : May 10 00:14:38 2033 GMT
Subject: O = [redacted], CN = My Name, emailAddress = [email protected]
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (8192 bit)
Modulus:
[... snip]
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Extended Key Usage:
E-mail Protection
X509v3 Subject Key Identifier:
A6:C7:14:89:03:6A:AD:95:9D:02:8C:D7:B3:0F:C6:5E:12:23:3C:FE
X509v3 Authority Key Identifier:
6F:73:01:97:F5:BE:29:68:47:56:24:35:91:8F:1C:6F:9D:80:8A:1D
X509v3 Subject Alternative Name:
email:[email protected]
Signature Algorithm: sha512WithRSAEncryption
Signature Value:
[... snip]
注 3
pcks12 信息的输出如下所示
MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
Certificate bag
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256