【发布时间】:2020-12-10 00:19:31
【问题描述】:
我正在尝试为使用 SSL 身份验证的 Kafka 使用者设置密钥库,但我不断遇到身份验证问题。我有一个不使用密钥库的 Python 示例。所以,我相信我在填充密钥库的方式上做错了。 (注意:我不能只在命令行上执行此操作,因为证书需要按轮换计划进行更改,因此我需要使用 Java 代码自动执行此操作。)
这是我填充密钥库的方式:
String cert = "-----BEGIN CERTIFICATE-----\n" +
"MIIEmTCCAoGgAwIBAgIUew1ANL9cTyhxLIo1ZpWLdKT4nOwwDQYJKoZIhvcNAQEL\n" +
...
"fjv+XLmCfL1IKqcsEYmEPmyf5Knwk0mO7gtw1fg=\n" +
"-----END CERTIFICATE-----\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIFtTCCA52gAwIBAgIUe6eKhfms7ldZ78MxKiMzwFQNhsYwDQYJKoZIhvcNAQEL\n" +
...
"jyDgNvJnm3g5eP6KUm9NNo7Le6lZoZhC3g==\n" +
"-----END CERTIFICATE-----\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIG5DCCBMygAwIBAgITKgAABSItHRkNBBF47gAAAAAFIjANBgkqhkiG9w0BAQsF\n" +
...
"CF2TF5vdlOAUtvrJdnYgqNlSQHPAPeBP1runuwCV9ziZBTlra03cFw==\n" +
"-----END CERTIFICATE-----\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIF3TCCA8WgAwIBAgITXAAAAALRq61XLgYZigAAAAAAAjANBgkqhkiG9w0BAQ0F\n" +
...
"7ulMCI8RqFm3p32fs//+8o0=\n" +
"-----END CERTIFICATE-----\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIFEzCCAvugAwIBAgIQORoOm2GoxqBGK3xSM9br+zANBgkqhkiG9w0BAQ0FADAc\n" +
...
"mBSMIdx3Iw==\n" +
"-----END CERTIFICATE-----\n";
String privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEogIBAAKCAQEAstlhsvxwbG8fVawH++HXq7mrqy9xfjIWwD45JAJSlstBBoBE\n" +
...
"TovqdueB5W7DR0FVYoxmLj3vcG6fy/j9f+O9fb/mo94Ma39Px3I=\n" +
"-----END RSA PRIVATE KEY-----";
String rootCA = "-----BEGIN CERTIFICATE-----\n" +
"MIIFEzCCAvugAwIBAgIQORoOm2GoxqBGK3xSM9br+zANBgkqhkiG9w0BAQ0FADAc\n" +
...
"mBSMIdx3Iw==\n" +
"-----END CERTIFICATE-----";
final PEMParser rootCaParser = new PEMParser(new StringReader(rootCA));
final PEMParser certParser = new PEMParser(new StringReader(certificate));
final PEMParser keyParser = new PEMParser(new StringReader(privateKey));
final X509Certificate rootCa = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate((X509CertificateHolder) rootCaParser.readObject());
final X509Certificate cert = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate((X509CertificateHolder) certParser.readObject());
final PrivateKey key = new JcaPEMKeyConverter().setProvider(new BouncyCastleProvider()).getKeyPair((PEMKeyPair) keyParser.readObject()).getPrivate();
KeyStore keystore = KeyStore.getInstance("jks");
char[] keyStorePass = config.getKeystorePassword().toCharArray();
char[] trustStorePass = config.getTruststorePassword().toCharArray();
keystore.load(null);
final Certificate[] chain = { cert };
keystore.setKeyEntry("privateKey", key, keyStorePass, chain);
keystore.setCertificateEntry("CARoot",rootCa);
keystore.setCertificateEntry("localhost", cert);
try (FileOutputStream out = new FileOutputStream(config.getKeystoreLocation())) {
keystore.store(out, keyStorePass);
}
在测试密钥库时,我注意到私钥(别名为 privatekey)显示的证书链长度为 1。这是不对的,因为实际的证书链的长度应该为 5。所以,我认为链被截断,就像代码没有正确地将证书链解析为 5 个证书,但只解析为一个。
如果我通过运行将证书(带链)附加到私钥:
cat pk cert > pkWithChain.pem
并设置 PKCS12 记录,例如:
openssl pkcs12 -export -in pkWithChain.pem -inkey pk -name pkWithChain > pkWithChain.p12
然后将其导入我的密钥库,例如:
keytool -importkeystore -srckeystore pkWithChain.p12 -destkeystore keystore.jks -srcstoretype pkcs12 -alias pkwithchain
当我像这样检查密钥库中的密钥时:
keytool -list -v -keystore keystore.jks
我手动放在那里的私钥的证书长度为 5,但我通过 Java 放在那里的私钥的证书长度为 1。
如何以编程方式将正确的(整个)证书链放入密钥库? (另外,我还需要做些什么来为 Kafka 正确设置我的密钥库吗?我的 Kafka 配置/设置已被验证为正确。密钥库是问题所在。)
【问题讨论】:
标签: java ssl apache-kafka bouncycastle keystore