我不确定我的问题/解释是否太长,因为我没有得到答案。现在的简短问题是:
使用时
SSL_CTX_use_PrivateKey_file
功能;为什么我会得到
139923876902592:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:
139923876902592:error:0906A065:PEM routines:PEM_do_header:bad decrypt:pem_lib.c:483:
139923876902592:error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib:ssl_rsa.c:669:
ERROR: Failed to set private key file /home/jocke/ca/intermediate/private/xxx.key.pem. ERROR:
当我输入错误密码时,
39814590265024:error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch:x509_cmp.c:330:
ERROR: Failed to set private key file /home/jocke/ca/intermediate/private/xxx.key.pem. ERROR:
我什么时候输入正确的密码?
旧帖:
抱歉这里的布局,但工具说是代码但没有格式化为代码,但我不知道它是什么,所以我将“编码”所有内容。
好吧 jww,我以为我做到了。让我确切地展示我在做什么,并解释为什么我认为我是对的(尽管我显然不是):
1) 生成根 CA 密钥/证书
目录设置
mkdir ~/ca/
cd ~/ca
mkdir certs crl newcerts private
chmod 700 private
index.txt 文件是 OpenSSL ca 工具存储证书数据库的位置。请勿手动删除或编辑此文件。它现在应该包含一个引用中间证书的行。
touch index.txt
echo 1000 > serial
创建~/ca/openssl.cnf,如下面的“根CA配置文件”,并确保dir值正确
openssl genrsa -aes256 -out private/ca.key.pem 4096
chmod 400 private/ca.key.pem
警告:无论何时使用 req 工具,都必须指定一个配置文件以与 -config 选项一起使用,否则 OpenSSL 将默认为 /etc/pki/tls/openssl.cnf。
注意:有效期长,使用 20 年(7300 天)
openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem
chmod 444 certs/ca.cert.pem
验证证书:
openssl x509 -noout -text -in certs/ca.cert.pem
根 CA 私钥:~/ca/private/ca.key.pem
根 CA 证书:~/ca/certs/ca.cert.pem
2) 生成中间 CA 密钥/证书
目录设置
mkdir ~/ca/indermediate
cd ~/ca/indermediate
mkdir certs crl csr newcerts private
chmod 700 private
touch index.txt
echo 1000 > serial
echo 1000 > ~/ca/intermediate/crlnumber
创建 ~/ca/intermediate/openssl.cnf 像下面的“中间 CA 配置文件”,并确保 dir 值正确
cd ~/ca
创建中间 CA 私钥:
openssl genrsa -aes256 -out intermediate/private/intermediate.key.pem 4096
chmod 400 intermediate/private/intermediate.key.pem
创建证书签名请求 (CSR):(确保指定中间 CA 配置文件!)
cd ~/ca
openssl req -config intermediate/openssl.cnf -new -sha256 -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem
使用根证书和 CSR 创建中间 CA 证书:(确保指定 ROOT CA 配置文件!!!)
注意:有效期较短,使用 10 年(3650 天)
openssl ca -config openssl.cnf -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
chmod 444 intermediate/certs/intermediate.cert.pem
验证中间证书:
openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
中间 CA 私钥:~/ca/intermediate/private/intermediate.key.pem
中级 CA 证书:~/ca/intermediate/certs/intermediate.cert.pem
3) 创建证书链文件
当应用程序(例如,Web 浏览器)尝试验证由中间 CA 签名的证书时,它还必须根据根证书验证中间证书。
要完成信任链,请创建一个 CA 证书链以呈现给应用程序。
要创建 CA 证书链,请将中间证书和根证书连接在一起。
稍后我们将使用此文件来验证中间 CA 签署的证书。
cat intermediate/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem
chmod 444 intermediate/certs/ca-chain.cert.pem
证书链文件:~/ca/intermediate/certs/ca-chain.cert.pem
4) 签署服务器和客户端证书
使用中间 CA 签署证书。
创建密钥:
cd ~/ca/
openssl genrsa -aes256 -out intermediate/private/myinternetaddr.key.pem 2048
chmod 400 intermediate/private/myinternetaddr.key.pem
创建证书签名请求 (CSR):
openssl req -config intermediate/openssl.cnf -key intermediate/private/myinternetaddr.key.pem -keyform PEM -new -sha256 -out intermediate/csr/myinternetaddr.csr.pem
创建服务器证书:
openssl ca -config intermediate/openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in intermediate/csr/myinternetaddr.csr.pem -out intermediate/certs/myinternetaddr.cert.pem
chmod 444 intermediate/certs/myinternetaddr.cert.pem
cat index.txt
对于网站管理员:以下行被视为“代码” - 为什么?上面类似的行不是。
客户端私钥:~/ca/intermediate/private/myinternetaddr.key.pem
客户证书签名请求:~/ca/intermediate/csr/myinternetaddr.csr.pem
客户证书:~/ca/intermediate/certs/myinternetaddr.cert.pem
验证证书:
openssl x509 -noout -text -in intermediate/certs/myinternetaddr.cert.pem
使用我们之前创建的 CA 证书链文件 (ca-chain.cert.pem) 来验证新证书是否具有有效的信任链。
$ openssl verify -CAfile intermediate/certs/ca-chain.cert.pem intermediate/certs/myinternetaddr.cert.pem
intermediate/certs/myinternetaddr.cert.pem: OK
然后我运行程序,如下所示。如您所见,我正在使用证书链文件(已验证具有服务器证书 - 见底部)以及服务器证书的相应私钥文件。
SSL_library_init();
SSL_METHOD const * method = SSLv3_server_method();
if (!method)
{
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
SSL_CTX * ctx = SSL_CTX_new(method);
if (!ctx)
{
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
if (!SSL_CTX_use_certificate_chain_file(ctx, "~/ca/intermediate/certs/ca-chain.cert.pem"))
{
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) private_key_file_password);
SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
if (SSL_CTX_use_PrivateKey_file(ctx, "~/ca/intermediate/private/myinternetaddr.key.pem", SSL_FILETYPE_PEM) != 1)
{
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
密码回调:
static int pem_passwd_cb(char * buf, int size, int rwflag, void * userdata)
{
char const * const password = (char const * const) userdata;
Logger & logger = Logger::get_instance();
logger << "Setting password to [" << password << "]";
logger.log_info();
strncpy(buf, (char *) password, size);
buf[size - 1] = '\0';
fprintf(stdout, "BUFLEN: %d\nBUF: [%s]\n", (int) strlen(buf), buf);
return strlen(buf);
}
现在,完成以下操作后,我认为一切都应该没问题。
$ openssl req -config intermediate/openssl.cnf -key intermediate/private/myinternetaddr.key.pem -new -sha256 -out intermediate/csr/myinternetaddr.csr.pem
Enter pass phrase for intermediate/private/myinternetaddr.key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:SE
State or Province Name [England]:Sweden
Locality Name []:NA
Organization Name [Alice Ltd]:NA
Organizational Unit Name []:NA
Common Name []:Jocke
Email Address []:yyy@hotmail.com
$ openssl ca -config intermediate/openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in intermediate/csr/myinternetaddr.csr.pem -out intermediate/certs/myinternetaddr.cert.pem
Using configuration from intermediate/openssl.cnf
Enter pass phrase for ~/ca/intermediate/private/intermediate.key.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 4098 (0x1002)
Validity
Not Before: Aug 13 20:58:46 2016 GMT
Not After : Aug 23 20:58:46 2017 GMT
Subject:
countryName = SE
stateOrProvinceName = Sweden
localityName = NA
organizationName = NA
organizationalUnitName = NA
commonName = Jocke
emailAddress = yyy@hotmail.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Server
Netscape Comment:
OpenSSL Generated Server Certificate
X509v3 Subject Key Identifier:
D5:D6:F4:38:24:18:41:F7:F0:29:9F:99:6C:D3:08:38:CE:35:B8:43
X509v3 Authority Key Identifier:
keyid:2C:EB:99:69:BE:00:EE:C2:FD:86:B7:CF:6C:AD:47:4E:65:AA:90:5A
DirName:/C=SE/ST=Sweden/L=/O=Joachim Person/CN=Joachim Person/emailAddress=xxx@gmail.com
serial:10:00
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
Certificate is to be certified until Aug 23 20:58:46 2017 GMT (375 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
但显然不是——为什么?