支付寶集成時的InvalidKeySpecException


近來在集成第三方支付---支付寶,在集成的過程中嚴格按照支付寶開發者平台所發布的說明文檔和Demo,在我的測試機上可以完美的運行,但是在別人的手機無論怎么就是調用不起來,總是彈出"remote call failed". 翻來復去,代碼檢查了好幾遍,總是找不到錯誤在哪。

然后,仔細地查看了一下LogCat,發現一條Warning,顯示是InvalidKeySpecException異常,顯示如下:

09-23 20:03:34.735: W/System.err(24906): java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
09-23 20:03:34.740: W/System.err(24906): 	at org.apache.harmony.xnet.provider.jsse.OpenSSLKey.getPrivateKey(OpenSSLKey.java:124)
09-23 20:03:34.740: W/System.err(24906): 	at org.apache.harmony.xnet.provider.jsse.OpenSSLRSAKeyFactory.engineGeneratePrivate(OpenSSLRSAKeyFactory.java:64)
09-23 20:03:34.740: W/System.err(24906): 	at java.security.KeyFactory.generatePrivate(KeyFactory.java:186)
09-23 20:03:34.740: W/System.err(24906): 	at com.slanissue.apps.mobile.bevarhymes.util.Rsa.sign(Rsa.java:68)
09-23 20:03:34.740: W/System.err(24906): 	at com.slanissue.apps.mobile.bevarhymes.PayActivity.executeAliPay(PayActivity.java:1055)
09-23 20:03:34.740: W/System.err(24906): 	at com.slanissue.apps.mobile.bevarhymes.PayActivity.access$9(PayActivity.java:1050)
09-23 20:03:34.740: W/System.err(24906): 	at com.slanissue.apps.mobile.bevarhymes.PayActivity$5.onSuccess(PayActivity.java:443)
09-23 20:03:34.740: W/System.err(24906): 	at com.loopj.android.http.JsonHttpResponseHandler$1$1.run(JsonHttpResponseHandler.java:125)
09-23 20:03:34.740: W/System.err(24906): 	at android.os.Handler.handleCallback(Handler.java:730)
09-23 20:03:34.740: W/System.err(24906): 	at android.os.Handler.dispatchMessage(Handler.java:92)
09-23 20:03:34.740: W/System.err(24906): 	at android.os.Looper.loop(Looper.java:176)
09-23 20:03:34.740: W/System.err(24906): 	at android.app.ActivityThread.main(ActivityThread.java:5454)
09-23 20:03:34.740: W/System.err(24906): 	at java.lang.reflect.Method.invokeNative(Native Method)
09-23 20:03:34.740: W/System.err(24906): 	at java.lang.reflect.Method.invoke(Method.java:525)
09-23 20:03:34.740: W/System.err(24906): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
09-23 20:03:34.740: W/System.err(24906): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
09-23 20:03:34.740: W/System.err(24906): 	at dalvik.system.NativeStart.main(Native Method)
09-23 20:03:34.745: W/System.err(24906): Caused by: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
09-23 20:03:34.745: W/System.err(24906): 	at org.apache.harmony.xnet.provider.jsse.NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(Native Method)
09-23 20:03:34.745: W/System.err(24906): 	at org.apache.harmony.xnet.provider.jsse.OpenSSLKey.getPrivateKey(OpenSSLKey.java:122)
09-23 20:03:34.745: W/System.err(24906): 	... 16 more

  點擊第8行進去,發現錯誤在這兒:

1             PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
2                     Base64.decode(privateKey));
3             KeyFactory keyf = KeyFactory.getInstance("RSA");
4             PrivateKey priKey = keyf.generatePrivate(priPKCS8);

但是這里顯然沒有錯啊?這到底是怎么回事呢??

經過在博客和StackOverFlow上查詢,發現原來是這樣的:(我的測試機比較早了,Android版本是4.0.3的,但是用的其它人的手機版本基本上都在4.3.x)

在Android4.1.0之前的版本,代碼行

1 KeyFactory keyf = KeyFactory.getInstance("RSA");
View Code

是工作正常的。但是在4.1.0之后,這個就不能正常工作了,需要將該代碼改變成:

1 KeyFactory keyf = KeyFactory.getInstance("RSA", "BC");
View Code

然后就研究了一下這個方法的作用,API上面說的是:“為指定提供程序中的指定算法生成 KeyFactory 對象”;

即:KeyFactory.getInstance(String algorithm, String provider);中的algorithm為“指定算法”,provider為“指定提供程序”。

或許是因為Android虛擬機Dalvik對KeyFactory的實現中,默認的provider在4.1.0之后由"BC"改為了其它的了。當然,僅是猜測。

還好最終解決了問題。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM