# 生成根证书密钥对 (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl genrsa -des3 -out rootCA.key 2048 # 输入保护密码 Enter PEM pass phrase: AVe384L3oCgN # 再次输入密码,请保存好密码,在生成,签发和验证都需要 # 后面会有很多密码,如果搞不清楚,建议全部用一个密码 # 密码可以在 https://1password.com/zh-cn/password-generator 生成 Verifying - Enter PEM pass phrase: AVe384L3oCgN # 生成根证书,有效期10年 (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt # 输入保护密码 Enter pass phrase for rootCA.key: AVe384L3oCgN You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- # 国家简称 Country Name (2 letter code) [AU]:CN # 省份,格式随意 State or Province Name (full name) [Some-State]:Jiang Su # 市,格式随意 Locality Name (eg, city) []:Su Zhou # 公司:格式随意 Organization Name (eg, company) [Internet Widgits Pty Ltd]:YCMJ # 部门:格式随意 Organizational Unit Name (eg, section) []:DEV # CN:根证书写死rootCA Common Name (e.g. server FQDN or YOUR name) []: rootCA # 邮箱 Email Address []:caszhou86@gmail.com # 生成服务端证书密钥对 (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl genrsa -out server.key 2048 # 创建服务端CSR配置 (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog vim openssl.cnf [req] default_bits = 2048 distinguished_name = req_distinguished_name req_extensions = req_ext x509_extensions = v3_req prompt = no
[req_distinguished_name] countryName = CN stateOrProvinceName = Jiang Su localityName = Su Zhou organizationName = YCMJ organizationalUnitName = DEV # CN:必须是你server地址 commonName = mqtt-server.sipa.com
[req_ext] subjectAltName = @alt_names
[v3_req] subjectAltName = @alt_names
[alt_names] # server 地址 DNS.1 = mqtt-server.sipa.com # server ip IP.1 = 127.0.0.1 # 生成CSR (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl req -new -key server.key -config openssl.cnf -out server.csr # 使用根证书,签发服务器证书,5年有效期 (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 1825Certificate request self-signature ok subject=C = CN, ST = Jiang Su, L = Su Zhou, O = YCMJ, CN = mqtt-server.sipa.com Enter pass phrase for rootCA.key: AVe384L3oCgN # 生成客户端证书密钥对 (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl genrsa -out client.key 2048 # 生成客户端CSR (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl req -new -key client.key -out client.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:Jiang Su Locality Name (eg, city) []:Su Zhou Organization Name (eg, company) [Internet Widgits Pty Ltd]:YCMJ Organizational Unit Name (eg, section) []:DEV # 客户端FQDN或者名字 Common Name (e.g. server FQDN or YOUR name) []:client Email Address []:
Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: # 使用根证书签发客户端证书,有效期1年 (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl x509 -req -in client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out client.crt -days 365 Certificate request self-signature ok subject=C = CN, ST = Jiang Su, L = Su Zhou, O = YCMJ, OU = DEV, CN = client Enter pass phrase for rootCA.key: AVe384L3oCgN # 验证证书 (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl verify -CAfile rootCA.crt server.crt server.crt: OK (base) zhouxiajie@zhouxiajiedeMBP ~/Downloads/blog openssl verify -CAfile rootCA.crt client.crt client.crt: OK
## NOTE: ## This config file overrides data/configs/cluster.hocon, ## and is merged with environment variables which start with 'EMQX_' prefix. ## ## Config changes made from EMQX dashboard UI, management HTTP API, or CLI ## are stored in data/configs/cluster.hocon. ## To avoid confusion, please do not store the same configs in both files. ## ## See https://www.emqx.io/docs/en/latest/configuration/configuration.html for more details. ## Configuration full example can be found in etc/examples
cluster { name = emqxcl discovery_strategy = manual }
## EMQX provides support for two primary log handlers: `file` and `console`, with an additional `audit` handler specifically designed to always direct logs to files. ## The system's default log handling behavior can be configured via the environment variable `EMQX_DEFAULT_LOG_HANDLER`, which accepts the following settings: ## ## - `file`: Directs log output exclusively to files. ## - `console`: Channels log output solely to the console. ## ## It's noteworthy that `EMQX_DEFAULT_LOG_HANDLER` is set to `file` when EMQX is initiated via systemd `emqx.service` file. ## In scenarios outside systemd initiation, `console` serves as the default log handler.
## Read more about configs here: https://www.emqx.io/docs/en/latest/configuration/logs.html
while (bis.available() > 0) { caCert = (X509Certificate)cf.generateCertificate(bis); }
// load client certificate bis = newBufferedInputStream(newFileInputStream(crtFile)); X509Certificatecert=null; while (bis.available() > 0) { cert = (X509Certificate)cf.generateCertificate(bis); }
// load client private key PEMParserpemParser=newPEMParser(newFileReader(keyFile)); Objectobject= pemParser.readObject(); PEMDecryptorProviderdecProv=newJcePEMDecryptorProviderBuilder().build(password.toCharArray()); JcaPEMKeyConverterconverter=newJcaPEMKeyConverter().setProvider("BC"); KeyPair key; if (object instanceof PEMEncryptedKeyPair) { System.out.println("Encrypted key - we will use provided password"); key = converter.getKeyPair(((PEMEncryptedKeyPair)object).decryptKeyPair(decProv)); } else { System.out.println("Unencrypted key - no password needed"); key = converter.getKeyPair((PEMKeyPair)object); } pemParser.close();
// CA certificate is used to authenticate server KeyStorecaKs= KeyStore.getInstance(KeyStore.getDefaultType()); caKs.load(null, null); caKs.setCertificateEntry("ca-certificate", caCert); TrustManagerFactorytmf= TrustManagerFactory.getInstance("X509"); tmf.init(caKs);
// client key and certificates are sent to server so it can authenticate // us KeyStoreks= KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(null, null); ks.setCertificateEntry("certificate", cert); ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), newjava.security.cert.Certificate[] {cert}); KeyManagerFactorykmf= KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, password.toCharArray());