java - SSL 问题 : alert number 46 (sslv3 alert certificate unknown)

标签 java ssl openssl bouncycastle haproxy

我遇到了 的问题(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-file 时,就会出现上述问题。

用例

我正在使用 HAPROXY 进行 ssl 终止。我有自签名 ca.crt,ca.pem,server.crt,server.pem 和 client.crt,client.key,crl.pem

工作场景

我使用 Certificate Generate 生成了自签名证书

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

当我使用 Certificate Generate 生成证书时,上面的配置在使用和不使用 crl 文件时都能很好地工作

非工作场景

我使用 Java 充气城堡库生成所有证书。

客户端证书生成
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文件然后它与客户端证书一起使用。
但是当我包括 crl 文件到 haproxy 配置然后它会给出 警报编号 46(sslv3 警报证书未知)错误。

我已经使用 openssl 进行了验证
cat client3.pem | openssl verify -CAfile ca.crt

返回 好的 .
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

任何帮助对我都非常有用。

最佳答案

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

关于java - SSL 问题 : alert number 46 (sslv3 alert certificate unknown),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59631338/

相关文章:

java - Spring JPA - 将外键映射为主键 [MySQL]

java - X509TrustManager - 未调用 checkServerTrusted - 是否缓存了受信任的服务器证书或是否有获取证书链的方法?

java - 如果我通过 Hostgator 购买了 SSl,我该如何签署 Java 小程序

makefile - 使用 MinGW/MSYS 编译 OpenSSL 时出错

java - java中的字符串转换抛出数组索引超出范围异常

java - fragment 中更改主题(setTheme)类android Utils "this"错误

java - 如何使工具提示对鼠标事件透明?

http - tomcat访问8443端口

c - 使用 OpenSSL 从内存中读取证书文件而不是文件

c - 解密后的文件仍然是加密的