使用 Java 通过密钥、证书和 cacert 文件而不是 .p12 文件连接到 RabbitMQ (TLS)
Connecting using Java to RabbitMQ (TLS) with a key, a cert and a cacert file instead of a .p12 file
我有一个关于如何使用 java 和 TLS 连接到远程 RabbitMQ 机器的问题。
在 java 中,如果我使用 .p12 密钥和以下代码,我可以连接到 UAT 机器:
{
char[] keyPassphrase = "password".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(this.getClass().getClassLoader().getResourceAsStream("rmq.uat.p12"), keyPassphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keyPassphrase);
TrustManager[] trustAllCerts = new TrustManager[]{
new X509ExtendedTrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException {}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException {}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException {}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException {}
}
};
SSLContext c = SSLContext.getInstance("TLSv1.2");
c.init(kmf.getKeyManagers(), trustAllCerts, null);
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(rmqHost);
factory.setPort(rmqPort);
factory.setUsername(rmqUsername);
factory.setPassword(rmqPassword);
factory.setVirtualHost(vhost);
factory.useSslProtocol(c);
// factory.enableHostnameVerification();
conn = factory.newConnection();
channel = conn.createChannel();
}
在我的 DEV RabbitMQ 机器上,我有一系列证书:rmq_ca.dev.crt(证书)、rmq_cert.crt(证书)和 rmq_key.dev.key(密钥)。而且我找不到允许我使用这 3 个文件而不是 .p12 文件进行连接的 java 代码...
使用 nodejs,我可以使用以下代码进行连接:
let opts = {
key: fs.readFileSync(path.join(appRoot, 'rmq_key.dev.key')),
cert: fs.readFileSync(path.join(appRoot, 'rmq_cert.dev.crt')),
ca: [fs.readFileSync(path.join(appRoot, 'rmq_ca.dev.crt'))],
rejectUnauthorized: false
};
...
const rmq_string = `${protocol}://${user}:${pass}@${hosts}:${port}/${vhost}`;
...
amqp.connect(rmq_string, opts, (error0, connection) => {
...
}
关于如何让它在 java 端工作的任何想法?谢谢!
我确实找到了一个解决方法 - 从 3 个文件(rmq_key.dev.key、rmq_cert.dev.crt 和 rmq_ca.dev.crt)我可以使用以下命令生成一个 .p12 密钥文件
openssl pkcs12 -export -out cert.p12 -inkey rmq_key.dev.key -in rmq_cert.dev.crt -certfile rmq_ca.dev.crt
Enter Export Password: password
Verifying - Enter Export Password: password
并在我的 java 程序中使用这个新生成的密钥 (cert.p12)。
我看到了一些像 这样的答案,它展示了如何直接从 java 程序而不是使用 OpenSsl 以编程方式生成 .p12 密钥,但我没有尝试它,因为我有一个可行的解决方案。
我有一个关于如何使用 java 和 TLS 连接到远程 RabbitMQ 机器的问题。
在 java 中,如果我使用 .p12 密钥和以下代码,我可以连接到 UAT 机器:
{
char[] keyPassphrase = "password".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(this.getClass().getClassLoader().getResourceAsStream("rmq.uat.p12"), keyPassphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keyPassphrase);
TrustManager[] trustAllCerts = new TrustManager[]{
new X509ExtendedTrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException {}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException {}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException {}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException {}
}
};
SSLContext c = SSLContext.getInstance("TLSv1.2");
c.init(kmf.getKeyManagers(), trustAllCerts, null);
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(rmqHost);
factory.setPort(rmqPort);
factory.setUsername(rmqUsername);
factory.setPassword(rmqPassword);
factory.setVirtualHost(vhost);
factory.useSslProtocol(c);
// factory.enableHostnameVerification();
conn = factory.newConnection();
channel = conn.createChannel();
}
在我的 DEV RabbitMQ 机器上,我有一系列证书:rmq_ca.dev.crt(证书)、rmq_cert.crt(证书)和 rmq_key.dev.key(密钥)。而且我找不到允许我使用这 3 个文件而不是 .p12 文件进行连接的 java 代码...
使用 nodejs,我可以使用以下代码进行连接:
let opts = {
key: fs.readFileSync(path.join(appRoot, 'rmq_key.dev.key')),
cert: fs.readFileSync(path.join(appRoot, 'rmq_cert.dev.crt')),
ca: [fs.readFileSync(path.join(appRoot, 'rmq_ca.dev.crt'))],
rejectUnauthorized: false
};
...
const rmq_string = `${protocol}://${user}:${pass}@${hosts}:${port}/${vhost}`;
...
amqp.connect(rmq_string, opts, (error0, connection) => {
...
}
关于如何让它在 java 端工作的任何想法?谢谢!
我确实找到了一个解决方法 - 从 3 个文件(rmq_key.dev.key、rmq_cert.dev.crt 和 rmq_ca.dev.crt)我可以使用以下命令生成一个 .p12 密钥文件
openssl pkcs12 -export -out cert.p12 -inkey rmq_key.dev.key -in rmq_cert.dev.crt -certfile rmq_ca.dev.crt
Enter Export Password: password
Verifying - Enter Export Password: password
并在我的 java 程序中使用这个新生成的密钥 (cert.p12)。
我看到了一些像