emq安装使用 以及ssl单向双向验证及代码实现 小白使用手册

1 openssl安装

opensll emq安装包及客户端下载路径

https://download.csdn.net/download/h4241778/12647477

用于证书生产

$ tar zxf openssl openssl-1.0.1.tar.gz

$ cd openssl-1.0.1

$ ./config --prefix=/usr/local

 我记得执行到这就可以了,openssl version 可查看版本
$ make

$ make clean

$ sudo make install


2 emq安装

emqx-ubuntu16.04-v4.1.1_amd64.deb 安装

sudo dpkg -i emqx-ubuntu16.04-v4.1.1_amd64.deb

自动安装在 /etc/emqx 目录下;修改emqx.conf需要知道

客户端连接端口默认:18083  admin public
ssl默认端口为8883,具体可以查看emqx.conf

3 ssl创建证书

3.1准备工作

在opt目录下创建ssl目录用来临时存储生成的证书文件
mkdir /opt/ssl
cd /opt/ssl/

生成证书索引库数据库文件
touch demoCA/newcerts/index.txt
touch demoCA/index.txt
touch demoCA/serial

指定第一个颁发证书的序列号
echo 01 > demoCA/serial

3.2 证书生成

3.2.1 CA证书生成
openssl req -x509 -new -days 3650 -keyout ca.key -out rootCA.crt -nodes
openssl req -x509 -new -days 3650 -keyout ca.key -out rootCA.crt -nodes
参数:
Country Name (2 letter code) [XX]:国家【中国---CN】
State or Province Name (full name) []:省份
Locality Name (eg, city) [Default City]:城市
Organization Name (eg, company) [Default Company Ltd]:组织名称
Organizational Unit Name (eg, section) []:组织单元名称
Common Name (eg, your name or your server's hostname) []:服务器IP
Email Address []: 邮箱地址


3.2.2 为server端生成证书
1生成私钥
openssl genrsa -out server.key 2048
2生成证书请求csr文件
openssl req -new -key server.key -out server.csr
参数填写与前面类似
A challenge password []: 密码
An optional company name []:公司名称
3生成证书
openssl ca -in server.csr -out server.crt -cert rootCA.crt -keyfile ca.key -days 3650

3.2.3 为Client端生成证书
1生成私钥
openssl genrsa -out client.key 2048
2生成证书请求:
openssl req -new -key client.key -out client.csr
参数与服务端证书生成类似,不过这里我用到ip是客户端ip
3生成证书
openssl ca -in client.csr -out client.crt -cert rootCA.crt -keyfile ca.key


4 ssl双向验证和单向验证ssl配置

修改 emqx.conf文件

4.1单向认证
## SSL Options
listener.ssl.external.handshake_timeout = 15
listener.ssl.external.keyfile = etc/certs/server-key.pem
listener.ssl.external.certfile = etc/certs/server-cert.pem

## 开启双向认证
## listener.ssl.external.cacertfile = etc/certs/rootca-cert.pem
## listener.ssl.external.verify = verify_peer
## listener.ssl.external.fail_if_no_peer_cert = true


4.2 双向认证
## SSL Options
listener.ssl.external.handshake_timeout = 15
listener.ssl.external.keyfile = etc/certs/server-key.pem
listener.ssl.external.certfile = etc/certs/server-cert.pem

## 开启双向认证
listener.ssl.external.cacertfile = etc/certs/cacert.pem
listener.ssl.external.verify = verify_peer
listener.ssl.external.fail_if_no_peer_cert = true

5 代码实现

 1 pom 依赖

   <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.47</version>

    </dependency> 

 2 建立连接时赋值进行如下处理:

MqttConnectOptions  mqttConnectOptions = new MqttConnectOptions();
//mqtt 建立连接时赋值 双向

mqttConnectOptions.setSocketFactory(SslUtil.getSocketFactory(rootCrtPath, 
clientCrtPath, clientKeyPath, clientPassword));


//单向         	

mqttConnectOptions.setSocketFactory(SslUtil.getSocketFactorySingle(rootCrtPath));

3 加载证书工具类实现








import javax.net.ssl.SSLSocketFactory;

import java.security.Security;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

public class SslUtil {
    public static SSLSocketFactory getSocketFactory(final String caCrtFile, final String crtFile, final String keyFile,
                                                    final String password) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        // load CA certificate
        PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
        X509Certificate caCert = (X509Certificate)reader.readObject();
        reader.close();

        // load client certificate
        reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
        X509Certificate cert = (X509Certificate)reader.readObject();
        reader.close();

        // load client private key
        reader = new PEMReader(
                new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
                new PasswordFinder() {
                    @Override
                    public char[] getPassword() {
                        return password.toCharArray();
                    }
                }
        );
        KeyPair key = (KeyPair)reader.readObject();
        reader.close();

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

        // client key and certificates are sent to server so it can authenticate us
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null, null);
        ks.setCertificateEntry("certificate", cert);
        ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, password.toCharArray());

        // finally, create SSL socket factory
        SSLContext context = SSLContext.getInstance("TLSv1.1");
        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        return context.getSocketFactory();
    }
    
    
    public static SSLSocketFactory getSocketFactorySingle(final String caCrtFile) throws Exception {
			Security.addProvider(new BouncyCastleProvider());
			
			// load CA certificate
			PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
			X509Certificate caCert = (X509Certificate)reader.readObject();
			reader.close();
			
		
			
			// CA certificate is used to authenticate server
//			KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
//			caKs.load(null, null);
//			caKs.setCertificateEntry("ca-certificate", caCert);
			//TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
			//tmf.init(caKs);
			
			// client key and certificates are sent to server so it can authenticate us
			KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());//"JKS"
			ks.load(null, null);
			ks.setCertificateEntry("ca-certificate", caCert);
			TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());//"PKIX"
	        tmf.init(ks);
			// finally, create SSL socket factory
			SSLContext context = SSLContext.getInstance("TLSv1.1");
			context.init(null, tmf.getTrustManagers(), new SecureRandom());
			
			
			
			
			//----------------------------------------------------------------
//			 CertificateFactory cAf = CertificateFactory.getInstance("X.509");
//		        FileInputStream caIn = new FileInputStream(caPath);
//		        X509Certificate ca = (X509Certificate) cAf.generateCertificate(caIn);
//		        KeyStore caKs = KeyStore.getInstance("JKS");
//		        caKs.load(null, null);
//		        caKs.setCertificateEntry("ca-certificate", ca);
//		        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
//		        tmf.init(caKs);
//		 
//		      
//		        SSLContext context = SSLContext.getInstance("TLSv1");
//		        context.init(null, tmf.getTrustManagers(), new SecureRandom());
//		 
//		        return context.getSocketFactory();
		
			
			
			
			return context.getSocketFactory();
			}
}

猜你喜欢

转载自blog.csdn.net/h4241778/article/details/107495925