在 Mosquitto MQTT SSL/TLS 实例和客户端 java 应用程序中使用 DigiCert 全局根 CA [英] Using DigiCert Global Root CA in a Mosquitto MQTT SSL/TLS instance and client java application

查看:74
本文介绍了在 Mosquitto MQTT SSL/TLS 实例和客户端 java 应用程序中使用 DigiCert 全局根 CA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用从 OpenSSL 生成的证书成功运行用于 TLS1.2 的 Mosquitto MQTT,并在 mosquitto 配置文件中使用.这也涉及到Java Client手动指定连接mosquitto的CA证书文件

I am running Mosquitto MQTT for TLS1.2 successfully with certificates generated from OpenSSL and using in the mosquitto configuration file. This also involves the Java Client to manually specify the CA certificate file which connects to mosquitto

我想使用存在于我的 Java 密钥库中的 DigiCert Global Root CA.

I want to use the DigiCert Global Root CA which exists in my Java keystore.

用于此的 Mosquitto 配置文件如下所示:

The Mosquitto configuration file for this looks like the following:

cafile .\m2mqtt_ca.crt

# PEM encoded server certificate.
certfile .\m2mqtt_srv.crt

# PEM encoded keyfile.
keyfile .\m2mqtt_srv.key

tls_version tlsv1.2

这些证书是使用 OpenSSL 使用以下命令生成的:

These certificates were generated using OpenSSL using the following commands:

# generate key
openssl genrsa -des3 -out m2mqtt_ca.key 2048

# create CA certificate
openssl req -new -x509 -days 3650 -key m2mqtt_ca.key -out m2mqtt_ca.crt

# create private key for the server
openssl genrsa -out m2mqtt_srv.key 2048

# create certificate request from CA
openssl req -new -out m2mqtt_srv.csr -key m2mqtt_srv.key

# verify and sign the certificate request
openssl x509 -req -in m2mqtt_srv.csr -CA m2mqtt_ca.crt -CAkey m2mqtt_ca.key -CAcreateserial -out m2mqtt_srv.crt -days 3650

它可以在客户端 java 应用程序中使用以下内容:

And it can be consumed in a client java app using the following:

package acme.messaging;

import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.Security;

public class SslUtil {

    public static final SSLSocketFactory Instance;

    static {
        Instance = SslUtil.getSocketFactory(
                "N:\\work\\acme\\mqtt-ssl\\messaging\\mqtt\\certs\\m2mqtt_ca.crt");
    }

    private static X509CertificateHolder loadCACert(String caCrtFile) throws IOException {
        PEMParser reader =
                new PEMParser(
                        new InputStreamReader(new ByteArrayInputStream(
                                Files.readAllBytes(Paths.get(caCrtFile)))));
        X509CertificateHolder caCert = (X509CertificateHolder) reader.readObject();
        reader.close();

        return caCert;
    }

    static SSLSocketFactory getSocketFactory(
            final String caCrtFile) {

        try {
            Security.addProvider(new BouncyCastleProvider());

            JcaX509CertificateConverter jcaX509CertificateConverter = new JcaX509CertificateConverter();

            X509CertificateHolder caCertificateHolder = loadCACert(caCrtFile);

            // CA certificate is used to authenticate server
            KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
            caKs.load(null, null);
            caKs.setCertificateEntry("ca-certificate", jcaX509CertificateConverter.getCertificate(caCertificateHolder));
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(caKs);

            // finally, create SSL socket factory
            SSLContext context = SSLContext.getInstance("TLSv1.2");

            context.init(null, tmf.getTrustManagers(), null);

            return context.getSocketFactory();
        } catch (Exception ex) {
            return null;
        }
    }
}

// consume
String uri = "ssl://localhost:1884";
String clientId = "1002";

final MqttMessage mqttMessage = new MqttMessage();
String messageText = "Some data";
mqttMessage.setPayload(messageText.getBytes());

try (MqttClient client = new MqttClient(uri, clientId)) {
    if (!client.isConnected()) {
        final MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName("acme-user");
        options.setPassword("acme-user".toCharArray());

        options.setSocketFactory(SslUtil.Instance);

        client.connect(options);
    }

    mqttMessage.setRetained(true);

    client.publish("test/writeme", mqttMessage);
}


问题

是否可以在 Mosquitto 中使用基于 DigiCert Global Root CA 的证书?

目前它存在于我的 Java Keystore 中:

At present it exists in my Java Keystore:

可以导出,但不确定是否可以在OpenSSL工作流中正确使用.我曾尝试在上述步骤中使用它,但这产生了错误.这个想法是生成相同的文件并将它们导入到蚊子配置中.

It can be exported, but not sure whether this can be used in the OpenSSL workflow correctly. I have tried using it in the steps above but this yielded errors. The idea being to generate the same files and import those into the mosquito configuration.

在这里我确实尝试使用生成的文件和从 DigiCert 下载的文件

Here I did try to use the generated file and a downloaded one from DigiCert

以下命令行在 DigiCert 网站

openssl req -new -newkey rsa:2048 -nodes -out localhost.csr -keyout localhost.key -subj "/C=GB/ST=Durham/L=Durham/O=quorum/CN=localhost"
Can't load ./.rnd into RNG
8016:error:2406F079:random number generator:RAND_load_file:Cannot open file:crypto\rand\randfile.c:88:Filename=./.rnd
Generating a RSA private key
......................................................................................................................................................................+++++
.....................................................................................................+++++
writing new private key to 'localhost.key'

注意:我不知道这里的事件顺序.

NOTE: I am lost with my order of events here.

然后这些:

openssl x509 -req -in localhost.csr -CA DigiCertAssuredIDRootCA.crt -CAkey localhost.key -CAcreateserial -out m2mqtt_srv.crt -days 3650

错误:

Signature ok
subject=C = GB, ST = Durham, L = Durham, O = quorum, CN = localhost
unable to load certificate
9896:error:0909006C:PEM routines:get_name:no start line:crypto\pem\pem_lib.c:745:Expecting: TRUSTED CERTIFICATE

也试过这个:

openssl x509 -req -in localhost.csr -CA DigiCertAssuredIDRootCA.crt -CAkey DigiCertAssuredIDRootCA.crt.pem -CAcreateserial -out m2mqtt_srv.crt -days 3650

错误:

Signature ok
subject=C = GB, ST = Durham, L = Durham, O = quorum, CN = localhost
unable to load certificate
12904:error:0909006C:PEM routines:get_name:no start line:crypto\pem\pem_lib.c:745:Expecting: TRUSTED CERTIFICATE

推荐答案

如评论中所述.

您不能作为受信任的 CA 签署证书(如果可以,您为什么要信任 CA?).

You can not sign a certificate as a trusted CA (if you could why would you ever trust the CA?).

您必须生成 CSR(证书签名请求)并将其发送给 CA,让他们签名(通常会向您收费).他们还将证明您拥有证书将代表的域.(LetsEncrypt 使用 certbot 工具为您完成这一切,并且免费).

You have to generate a CSR (Certificate Signing Request) and send this to the CA for them to sign it (and usually charge you for it). They will also prove that you own the domain the certificate will represent. (LetsEncrypt does this all for you using the certbot tool and will do it for free).

也没有受信任的 CA 会为 localhost 签署证书.

Also no trusted CA will ever sign a certificate for localhost.

这篇关于在 Mosquitto MQTT SSL/TLS 实例和客户端 java 应用程序中使用 DigiCert 全局根 CA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆