SSL问题:警报编号46(sslv3警报证书未知)

4

我被困在一个问题上,它涉及(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
bcpkix-jdk15on:1.58 - NIrav Modi
OpenSSL 1.1.1 11 Sep 2018 - NIrav Modi
我已经更新并测试过了,但问题仍然存在。 - NIrav Modi
@user207421,你是100%正确的。 - NIrav Modi
显示剩余5条评论
1个回答

3

你需要在CA证书中添加AKI和SKI扩展,以便通过HA代理验证CRL。


这帮助我弄清楚了为什么我为一些旧证书签发的CRL无法工作,所以谢谢! - lmars

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接