Android与mqtt双向SSL认证

Android与mqtt双向SSL认证

借鉴大佬博客:http://blog.linguofeng.com/

需要的工具:

portecle-1.9

生成ca.bks完成对服务器的自签名单向认证

需要提供ca.crt

$keytool -import\-alias mqtt.broker\-file ca.crt\-keypass password\-keystore ca.bks\-storetype BKS\-storepass passw0rd\-providerClass org.bouncycastle.jce.provider.BouncyCastleProvider\-providerpath bcprov-ext-jdk14-1.54.jar

MqttAndroidClientclint=...MqttConnectOptionsoptions=newMqttConnectOptions();InputStreaminput=this.getApplicationContext().getAssets().open("ca.bks");options.setSocketFactory(client.getSSLSocketFactory(input,"password"));

生成client.bks完成对客户端的认证,需要借portecle工具把pfx转成bks

$openssl pkcs12 -export -inkey client.key -in client.crt -out client.pfx$java -jar portecle.jar

生成client.pfx文件,然后打开

File -> New Keystore -> BKS-V1 -> Tools -> Import Key Pair -> choose -> client.pfx

pfx转化为bks的时候提示:

java.security.InvalidKeyException: Illegal key size

如果密钥大于128, 会抛出上述异常。因为密钥长度是受限制的, java运行时环境读到的是受限的policy文件,文件位于/jre/lib/security下, 这种限制是因为美国对软件出口的控制

解决办法也很简单:

去网上下载相应的jar包下载下来,替换jdk 与jre下两个jar包:local_policy.jar和US_export_policy.jar即可。

jdk对应jar包的路径:C:\Java\jdk1.7.0_25\jre\lib\security

jre对应jar包的路径:C:\Java\jre7\lib\security

根据需求转化JKS和BKS

Android与mqtt双向SSL认证_第1张图片

privateSSLSocketFactorygetSSLSocketFactory(Context context,Stringpassword)throwsMqttSecurityException{

try{

InputStream keyStore=context.getResources().getAssets().open("client.bks");

KeyStore km=KeyStore.getInstance("BKS");

km.load(keyStore,password.toCharArray());

KeyManagerFactory kmf=KeyManagerFactory.getInstance("X509");

kmf.init(km,password.toCharArray());

InputStream trustStore=context.getResources().getAssets().open("ca.bks");

KeyStore ts=KeyStore.getInstance("BKS");

ts.load(trustStore,password.toCharArray());

TrustManagerFactory tmf=TrustManagerFactory.getInstance("X509");

tmf.init(ts);

SSLContext ctx=SSLContext.getInstance("SSL");

ctx.init(kmf.getKeyManagers(),tmf.getTrustManagers(),null);

returnctx.getSocketFactory();

}catch(KeyStoreException|CertificateException|IOException|NoSuchAlgorithmException|KeyManagementException|UnrecoverableKeyException e){

throw newMqttSecurityException(e);

}

}

options.setSocketFactory(getSSLSocketFactory(context,"password"));

你可能感兴趣的:(Android与mqtt双向SSL认证)