Certificate操作

1.创建Certificate

//创建证书认证的principal(response里有证书、密钥。密钥丢失需要重置,请妥善保管)
CreatePrincipalWithCertResponse response = iotHubClient.createPrincipalWithCert(TEST_ENDPOINT_NAME, TEST_PRINCIPAL_NAME);

2.重置Certificate

//重置证书,可重新获得证书、密钥
RenewCertificateResponse response = iotHubClient.renewCertificate(TEST_ENDPOINT_NAME, TEST_PRINCIPAL_NAME);

3.使用MqttSDK实现双向认证示例代码

package com.packt.cookbook;

import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import sun.misc.BASE64Decoder;
import sun.security.provider.X509Factory;


public class App
{

    public static void main( String[] args )
    {
        String endpoint = "your-endpoint:1884";    //输入创建endpoint返回的SSL地址
        String username = "your-endpoint/god"; //输入创建thing返回的username
        String topic = "asdfasd"; //订阅的消息主题
        String privateKeyStr = "-----BEGIN RSA PRIVATE KEY---..your key..-----END RSA PRIVATE KEY-----";
        String clientCertStr = "-----BEGIN CERTIFICATE---..your certificate..-----END CERTIFICATE-----";
        String serverCertStr = "-----BEGIN CERTIFICATE----..your certificate..-----END CERTIFICATE-----";

        try {

            //generate the private key.
            PrivateKey privateKey = genPrivateKey(privateKeyStr);
            //generate the KeyManager of client, which includes client certificate and private key.
            KeyManager[] km = genKeyManager(clientCertStr, privateKey);
            //generate the trust Manager.
            TrustManager[] trustManagers = genTrustManager(serverCertStr);
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(km, trustManagers, null);
            MqttConnectOptions options = new MqttConnectOptions();
            options.setCleanSession(true);
            options.setUserName(username);
            options.setSocketFactory(ctx.getSocketFactory());
            System.out.println("initial client");
            MemoryPersistence persistence = new MemoryPersistence();

            //java-client为标识设备的ID,用户可自己定义,在同一个实例下,每个实体设备需要有一个唯一的ID
            MqttClient client = new MqttClient(endpoint, "your_id", persistence);
            System.out.println("Connecting to broker: "+endpoint);

            client.connect(options);
            System.out.println("Connected");
            System.out.println("subscribing topic");
            client.subscribe(topic);

            MqttMessage message = new MqttMessage();
            message.setPayload("15".getBytes());
            System.out.println("publishing msg to broker");
            client.publish(topic, message);

            client.disconnect();
        } catch (Exception e) {
            e.printStackTrace();

        }

    }

    public static PrivateKey genPrivateKey(String key) throws Exception {

        String privateKeyPEM = key;
        privateKeyPEM = privateKeyPEM.replace("-----BEGIN RSA PRIVATE KEY-----", "");
        privateKeyPEM = privateKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");
        System.out.println(privateKeyPEM);
        BASE64Decoder b64 = new BASE64Decoder();
        byte[] decoded = b64.decodeBuffer(privateKeyPEM);
        PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(decoded);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey privKey = kf.generatePrivate(keySpecPKCS8);
        return privKey;
    }

    public static KeyManager[] genKeyManager(String clientCertStr, PrivateKey privateKey) throws Exception {

        BASE64Decoder Base64 = new BASE64Decoder();
        byte [] decoded_cert = Base64.decodeBuffer(clientCertStr.replaceAll(X509Factory.BEGIN_CERT, "").
                replaceAll(X509Factory.END_CERT, ""));
        Certificate clientCert = CertificateFactory.getInstance("X.509")
                .generateCertificate(new ByteArrayInputStream(decoded_cert));
        KeyStore keyStore = KeyStore.getInstance("JCEKS");
        keyStore.load(null);
        keyStore.setCertificateEntry("cert-alias", clientCert);
        keyStore.setKeyEntry("key-alias", privateKey, "changeit".toCharArray(), new Certificate[] {clientCert});
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(keyStore, "changeit".toCharArray());
        KeyManager[] km = kmf.getKeyManagers();
        return km;
    }

    public static TrustManager[] genTrustManager(String serverCertStr) throws Exception {
        BASE64Decoder Base64 = new BASE64Decoder();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null  );
        byte [] decoded_server_cert = Base64.decodeBuffer(serverCertStr.
                replaceAll(X509Factory.BEGIN_CERT, "")
                .replaceAll(X509Factory.END_CERT, ""));

        Certificate serverCert = CertificateFactory.getInstance("X.509")
                .generateCertificate(new ByteArrayInputStream(decoded_server_cert));

        keyStore.setCertificateEntry("ca", serverCert);
        tmf.init((KeyStore) null);
        TrustManager[] trustManagers = tmf.getTrustManagers();
        return trustManagers;
    }
}