我被困在一个问题上,它涉及(SSL警报号46)
140097325019584:error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate
unknown:../ssl/record/rec_layer_s3.c:1528:SSL alert number 46
当我在haproxy配置中使用crl文件时,会出现上述问题。 用例 我正在使用HAPROXY进行ssl终止。我有自签名的ca.crt、ca.pem、server.crt、server.pem和client.crt、client.key、crl.pem。
工作场景
我使用证书生成生成了自签名证书。
HA代理配置
global
log 127.0.0.1 local0 debug
tune.ssl.default-dh-param 2048
defaults
log global
listen mqtt
bind *:2883
bind *:8883 ssl crt /etc/ssl/certs/server.pem verify required ca-file /etc/ssl/certs/ca.pem crl-file /etc/ssl/certs/crl.pem
mode tcp
option tcplog
option clitcpka # For TCP keep-alive
tcp-request content capture dst len 15
timeout client 3h #By default TCP keep-alive interval is 2hours in OS kernal, 'cat /proc/sys/net/ipv4/tcp_keepalive_time'
timeout server 3h #By default TCP keep-alive interval is 2hours in OS kernal
balance leastconn
# MQTT broker 1
server broker_1 ray-mqtt:1883 check send-proxy-v2-ssl-cn
# MQTT broker 2
# server broker_2 10.255.4.102:1883 check
这个配置使用 证书生成 生成的证书,可以在有或没有 CRL 文件的情况下正常工作。请注意,保留 HTML 标签,不要添加解释。
不可用的情况
我使用Java bouncy castle库生成所有证书。
客户端证书生成
public static X509Certificate generateClientCertificate(X509Certificate issuerCertificate, PrivateKey issuerPrivateKey, KeyPair keyPair, X500Name dnName, BigInteger serialNumber) throws IOException, OperatorCreationException, CertificateException {
JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(SHA_256_WITH_RSA).setProvider("BC");
JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
issuerCertificate, //here intermedCA is issuer authority
serialNumber, new Date(),
Date.from(Instant.now().plus(100, ChronoUnit.DAYS)),
dnName, keyPair.getPublic());
builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature));
builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));
X509Certificate x509Certificate = new JcaX509CertificateConverter()
.getCertificate(builder
.build(signerBuilder.build(issuerPrivateKey)));// private key of signing authority , here it is signed by intermedCA
return x509Certificate;
}
CRL 生成
private static X509CRL generateCrl(X509Certificate ca, PrivateKey caPrivateKey, PublicKey caPublicKey,
X509Certificate... revoked) throws Exception {
X509v2CRLBuilder builder = new X509v2CRLBuilder(
new X500Name(ca.getSubjectDN().getName()),
new Date()
);
builder.setNextUpdate(Date.from(Instant.now().plus(100000l, ChronoUnit.HOURS)));
for (X509Certificate certificate : revoked) {
builder.addCRLEntry(certificate.getSerialNumber(), new Date(), CRLReason.PRIVILEGE_WITHDRAWN.ordinal());
}
builder.addExtension(Extension.cRLNumber, false, new CRLNumber(BigInteger.valueOf(4)));
// builder.addExtension(Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifier(ca.getEncoded()));
builder.addExtension(Extension.authorityKeyIdentifier, false,
new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(caPublicKey));
JcaContentSignerBuilder contentSignerBuilder =
new JcaContentSignerBuilder(SHA_256_WITH_RSA_ENCRYPTION);
contentSignerBuilder.setProvider(BC_PROVIDER_NAME);
X509CRLHolder crlHolder = builder.build(contentSignerBuilder.build(caPrivateKey));
JcaX509CRLConverter converter = new JcaX509CRLConverter();
converter.setProvider(BC_PROVIDER_NAME);
return converter.getCRL(crlHolder);
}
在HAproxy配置中,如果我不包括crl-file,那么它可以使用客户端证书。但是,当我将crl-file包含到haproxy配置中时,它会出现alert number 46 (sslv3 alert certificate unknown)错误。我已经使用openssl进行验证。
cat client3.pem | openssl verify -CAfile ca.crt
该命令返回OK。
openssl s_client -connect haproxy:8883 -cert client3.crt -key client3.key -CAfile ca.crt
的输出结果如下:
CONNECTED(00000005)
depth=1 CN = *.ray.life
verify return:1
depth=0 CN = haproxy
verify return:1
---
Certificate chain
0 s:CN = haproxy
i:CN = *.ray.life
1 s:CN = *.ray.life
i:CN = *.ray.life
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIBujCCASOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDDAoqLnJh
eS5saWZlMB4XDTIwMDEwNzExMzIyOFoXDTIwMDQxNjExMzIyOFowEjEQMA4GA1UE
AwwHaGFwcm94eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0CAq/xYcCXWl
PJgs2+DeRRO5DRK813LIiRzdoMFeKrI9X5yXeNFzc6mSAS9EdFITM/HJYSvL/XhZ
p+Hu3N2f9ZR/zD2hpTq2PP0lK3Ev6gryXpWXoJU2SbtOyLsjPmw1y/+xHUjVv5B6
V+m7b0I3RYN8blcJIkjl7Gz83GMlMucCAwEAAaMdMBswDgYDVR0PAQH/BAQDAgeA
MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADgYEAnmIG9SXICU78Dz2eGbNN2znY
OGCpt7TBDkuXthStAFAyzHxZFKqexkelnJNMg19CbWzxGrPk6lxJQ+ebCGEYZwiZ
/WB9C1fQm+07/FEKVc1TCKv0odpTGRyXno4NePnFz6MCJGfVmec0huVPMD9fAbeJ
DlcWed88CL1MdgmkKoQ=
-----END CERTIFICATE-----
subject=CN = haproxy
issuer=CN = *.ray.life
---
Acceptable client certificate CA names
CN = *.ray.life
Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:ECDSA+SHA1:RSA+SHA224:RSA+SHA1
Shared Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1440 bytes and written 1488 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 1024 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
139659759231424:error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:../ssl/record/rec_layer_s3.c:1528:SSL alert number 46
任何帮助对我来说都非常有用。
bouncycastle
版本是哪个? - Boris