我一直在使用自行生成的 RSA 证书颁发机构来签署我的服务器证书,到目前为止一切正常。
遵循相同的模式,我尝试使用 ECDSA 签名,假设较小的密钥大小可能会让物联网设备变得更容易。 不幸的是我无法获得“工作”证书..
使用 openssl(OpenSSL 1.1.0l 2019 年 9 月 10 日)测试证书时,我收到一条错误消息(在服务器上),显示“tls_post_process_client_hello:没有共享密码”
服务器端:
openssl s_server -accept 1443 -www -key ec_server_key.pem -cert ec_server_cert.pem
Using default temp DH parameters
ACCEPT
140203753312320:error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher:../ssl/statem/statem_srvr.c:1419:
客户端:
openssl s_client -showcerts -connect localhost:1443 -CAfile ec_ca.pem
CONNECTED(00000003)
139868026671168:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1407:SSL alert number 40
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 176 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1618487596
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
---
使用 RSA 签名一切正常
这就是我使用 RSA 生成证书的方式
#!/bin/bash
# CERTIFICATE AUTHORITY
# generate CA private key
openssl genrsa -aes256 -passout pass:password -out rsa_ca_key.pem 4096
# generate CA public key
openssl req -new -x509 -sha256 -passin pass:password -days 365 -subj "/C=CO/ST=State/L=City/O=Organization/CN=AuthorityName" -key rsa_ca_key.pem -out rsa_ca.pem
# FOR EACH SERVER
# generate server private key
openssl genrsa -out rsa_server_key.pem 4096
# generate server certificate
openssl req -new -sha256 -subj "/CN=server_name" -key rsa_server_key.pem -out rsa_server.csr
# generate extension
echo subjectAltName = DNS:server_domain,IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf
# sign the server certificate
openssl x509 -req -sha256 -days 365 -in rsa_server.csr -CA rsa_ca.pem -CAkey rsa_ca_key.pem -CAcreateserial -out rsa_server_cert.pem -extfile extfile.cnf -passin pass:password
# clean up
rm extfile.cnf rsa_server.csr
这就是我使用 ECDSA 生成证书的方式
#!/bin/bash
# CERTIFICATE AUTHORITY
# generate CA private key
openssl ecparam -genkey -name secp256k1 -param_enc explicit | openssl ec -aes256 -passout pass:password -out ec_ca_key.pem
# generate CA public key
openssl req -new -x509 -sha256 -passin pass:password -days 365 -subj "/C=CO/ST=State/L=City/O=Organization/CN=AuthorityName" -key ec_ca_key.pem -out ec_ca.pem
# FOR EACH SERVER
# generate server private key
openssl ecparam -name secp256k1 -genkey -param_enc explicit -out ec_server_key.pem
# generate server certificate
openssl req -new -sha256 -subj "/CN=server_name" -key ec_server_key.pem -out ec_server.csr
# generate extension
echo subjectAltName = DNS:server_domain,IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf
# sign the server certificate
openssl x509 -req -sha256 -days 365 -in ec_server.csr -CA ec_ca.pem -CAkey ec_ca_key.pem -CAcreateserial -out ec_server_cert.pem -extfile extfile.cnf -passin pass:password
# clean up
rm extfile.cnf ec_server.csr
请在服务器端和客户端添加TLS版本和专用曲线,如下所示。
我尝试在 Windows 上通过
SslStream
(.NET) 使用 TLS 1.2 的 ECDSA 证书时遇到此错误。事实证明,虽然支持大量曲线来生成自签名证书,但只有一小部分曲线实际上适用于 Windows TLS 实现。
可以使用 powershell 命令
Get-TlsEccCurve
枚举支持的曲线。在 Win10 和 Server 2022 上,此命令仅列出三个曲线 - 尽管它看起来是可配置的。即 curve25519
、NistP256
和 NistP384
。
使用这些曲线的证书工作正常,而任何其他曲线都会生成“无共享密码”错误。如果使用 openssl 生成自签名证书,后两条曲线称为
secp256r1
(注意“r” - 还有一个不起作用的“k”)和 secp384r1
。曲线 25519 是在 openssl 中单独实现的,我无法让 openssl x509 使用此曲线签署证书请求。