1. 程式人生 > >Android RSA與Java RSA加密不同標準產生問題的解決方法

Android RSA與Java RSA加密不同標準產生問題的解決方法

最近做一個基於android的客戶端,客戶端與Java伺服器(MyEclipse自帶的Tomcat伺服器)的通訊需要實施安全方案。而本人是使用非對稱金鑰來對資料進行加密的,客戶端用公鑰加密,伺服器用私鑰解密。因此本人就用非對稱金鑰RSA演算法來實施。而本人在最開始的時候,在android平臺上與服務端初始化Cipher的時候都是使用一下這種方式:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
   cipher.init(Cipher.ENCRYPT_MODE, key);
   int blockSize = cipher.getBlockSize();

在這種情況下,android平臺的客戶端可以加密成功。而到了伺服器這一端卻無法解密,卻丟擲了以下異常:

“java.lang.Exception: Blocktype mismatch: 0”

在網上搜索了很多資料,有很多解決AndroidRSA與Java加密標準不同產生問題的方法。但是大部分解決方法都是說把android客戶端和tomcat伺服器上方法getInstance的引數寫成統一形式,如:“RSA/ECB/PKCS1Padding”或者“RSA/None/PKCS1Padding”。但是當本人改成相同形式的時候,還是出現上面的相同的異常:

“java.lang.Exception: Blocktype mismatch: 0”。

最後終於找到了一種最根本的方法,就是在伺服器上使用與Android客戶端RSA演算法中相同的Provider。android平臺上RSA加密演算法用的預設Provider是“org.bouncycastle.jce.provider.BouncyCastleProvider”。因此在服務端要想用私鑰解密android客戶端用公鑰加密的資料,在獲得Cipher物件的時候必須指定Provider為“org.bouncycastle.jce.provider.BouncyCastleProvider”。因此解決方法如下:

首先是環境配置:

第一步:

首先需要獲得“BouncyCastleProvider

”的jar包,該jar在百度裡搜尋就能找到,這裡提供一個下載包含“BouncyCastleProvider”的jar臨時的連結:

然後把下載好了的jar(bcprov-jdk15-143.jar)放在目錄:“F:\software_installed\Genuitec\Common\binary\com.sun.java.jdk.win32.x86_1.6.0.013\jre\lib”下。這裡目錄中粗體、斜體部分為本人MyEclipse的安裝目錄。

第二步:

需要在伺服器上的目錄:“F:\software_installed\Genuitec\Common\binary\com.sun.java.jdk.win32.x86_1.6.0.013\jre\lib\security”下(目錄中黑色粗體為本人MyEclipse安全目錄),修改java.security檔案,找到以下內容:

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.8=sun.security.smartcardio.SunPCSC
security.provider.9=sun.security.mscapi.SunMSCAPI

緊跟上面內容加上下面這句話:

security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

這裡的數字“10”是在數字“9”的基礎上遞增的。

最後重啟MyEclipse,重啟動MyEclipse後,如果在library中沒有發現該“bcprov-jdk15-143.jar”jar,那需要手工匯入改jar包到你之前建好的工程中。

其次程式碼:

最後在android客戶端和MyEclipse工程中獲取Cipher物件的程式碼如下:

android:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

MyEclipse工程裡:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding",new BouncyCastleProvider());

值得注意的有兩點:

1、程式碼中黑體和粗體要一致

2、程式碼中紫色部分為必須指定的Provider。

至此,由Android RSA與JavaRSA加密標準不同產生問題可以徹底解決了。