如何为 s/mime 签署证书并使用现有 CA 生成 pkcs12 存储?

如何为 s/mime 签署证书并使用现有 CA 生成 pkcs12 存储?

我想创建一个 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

相关内容