在mosquitto mqtt ssl/tls示例和客户机java应用程序中使用digicert全局根ca

tp5buhyn  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(446)

我正在为tls1.2成功运行mosquitto mqtt,证书是从 OpenSSL 并在mosquitto配置文件中使用。这还需要java客户机手动指定连接到mosquitto的ca证书文件
我想使用 DigiCert Global Root CA 存在于我的java密钥库中。

当前设置

此的mosquitto配置文件如下所示:

cafile .\m2mqtt_ca.crt

# PEM encoded server certificate.

certfile .\m2mqtt_srv.crt

# PEM encoded keyfile.

keyfile .\m2mqtt_srv.key

tls_version tlsv1.2

这些证书是使用openssl通过以下命令生成的:


# 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应用程序中使用以下内容:

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);
}

问题

是否可以使用基于 DigiCert Global Root CA 在莫斯奎托?
目前它存在于我的java密钥库中:

它可以导出,但不确定是否可以在openssl工作流中正确使用它。我已经尝试在上面的步骤中使用它,但这产生了错误。其思想是生成相同的文件并将其导入到蚊子配置中。

尝试使用openssl重用digicert证书时出错

在这里,我尝试使用生成的文件和从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'

注意:我对这里的事件顺序感到困惑。
然后这些:

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
mftmpeh8

mftmpeh81#

如评论中所述。
您不能将证书作为受信任的ca进行签名(如果可以,为什么您会信任ca?)。
您必须生成一个csr(证书签名请求)并将其发送给ca,以便他们对其进行签名(通常会向您收费)。它们还将证明您拥有证书所代表的域(letsencrypt使用certbot工具为您完成这一切,并将免费完成)。
此外,没有可信的ca将永远签署证书 localhost .

相关问题