需要把关键信息存在keystore证书文件中,但是java本身支持的keystore是jks的,而android不支持jks,只支持bks的,那么就需要将jks类型的证书转换成bks类型的,然后使用android支持的方式去读取证书内容。
android不支持jks如下说明,见stack说明:
http://stackoverflow.com/questions/9312193/does-android-support-jks-keystore-type
例如如下说明:
问题:
I am trying to connect to server using keystore which is provided by server team.
While sending service call to server first i created KeyStore Instance by using following api
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
It’s returning the keystore type as “BKS”.
The Keystore what server team sent is of type “.jks”(somename.jks) So, I am getting exception “Wrong version of key store”.
I tried by passing “JKS” to getInstance() of KeyStore by following way
KeyStore keystore = KeyStore.getInstance("JKS");
But here I am getting exception “KeyStore JKS implementation not found”.
Here is the piece of code:
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream instream = mContext.getAssets().open("somename.jks");
try {
trustStore.load(instream, "password".toCharArray());
} finally {
try {
instream.close();
} catch(Exception ignore) {
}
}
Please guide me to solve this problem
回答见下:
I think Android support 'only' BouncyCastle KeyStores (known as BKS)... You still can use Portecle
To convert it from JKS to BKS, should work like a charm (at least it worked for me when trying to store my .CRT into a BKS format ! ;)
'only' meaning, easily here :p, else you'll have to manipulate stuffs
需要转换的工具是Portecle
下载地址为
http://download.youkuaiyun.com/download/buxin_2008/4203250
使用方式见下:
http://ssl.chinassl.com/post/1cbcfb77_3b8d5cd
使用其实就是打开已有的keystore文件,然后修改jks为bks,然后重新保存证书就可以了,
最后使用的android读取证书的方式如下:
try {
String password = "xxxa";
AssetManager asset = this.getResources().getAssets();
InputStream ceris = asset.open("zlex.keystore");
// FileInputStream is = new FileInputStream(keyStorePath);
//KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore ks = KeyStore.getInstance("BKS");
ks.load(ceris, password.toCharArray());
ceris.close();
String alias = "xxxb";
RSAPrivateKey privateKey = (RSAPrivateKey) ks.getKey(alias, password.toCharArray());
System.out.println("私钥="+Base64.encode(privateKey.getEncoded()));
//-----------------------------------------------------------
CertificateFactory certificateFactory = CertificateFactory
.getInstance("X509");
InputStream keyis = asset.open("zlex.cer");
// FileInputStream in = new FileInputStream(certificatePath);
Certificate certificate = certificateFactory.generateCertificate(keyis);
keyis.close();
RSAPublicKey publicKey = (RSAPublicKey)certificate.getPublicKey();
System.out.println("公钥="+Base64.encode(publicKey.getEncoded()));
} catch (KeyStoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnrecoverableEntryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
其中xxxa为证书密码,xxxb为证书别名
这里需要将keystore文件,cer文件保存在assets中,如果保存在其他地方,请修改为相应目录,修改相应读取方式。