从Base64字符串解码的Android公钥抛出异常

时间:2014-09-13 22:56:08

标签: android string encoding base64 public-key

在解码用Base64编码的字符串以检索公钥时,我遇到了问题。

以下是我用来解密的方法:

public PublicKey decodeKyFrom64(String pub64) {
    try {
        byte[] keyBytes = Base64.decode(pub64.getBytes("utf-8"),Base64.DEFAULT);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
            try {
                PublicKey key = (PublicKey)keyFactory.generatePublic(spec);
                return key;
            } catch (InvalidKeySpecException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (NoSuchAlgorithmException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    } catch (UnsupportedEncodingException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    return null;
}

加密:

public String[] genKyForNewUser() {
    KeyPairGenerator kpg;
    KeyPair kp;
    PublicKey publicKey;
    PrivateKey privateKey;
    try {
        kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        kp = kpg.genKeyPair();
        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();
        String privKy = Base64.encodeToString(privateKey.getEncoded(), Base64.DEFAULT);
        String pubKy = Base64.encodeToString(publicKey.getEncoded(), Base64.DEFAULT);
        Log.d("Kript","Public: "+publicKey);
        Log.d("Kript","Private: "+privateKey);
        Log.d("Kript","PubKy: "+pubKy);
        Log.d("Kript","PrivKy: "+privKy);
        String[] kys = {pubKy,privKy};
        return kys;
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

这是我得到的例外:

09-14 00:36:56.293: W/System.err(27217): java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
09-14 00:36:56.343: W/System.err(27217):    at com.android.org.conscrypt.OpenSSLKey.getPublicKey(OpenSSLKey.java:101)
09-14 00:36:56.343: W/System.err(27217):    at com.android.org.conscrypt.OpenSSLRSAKeyFactory.engineGeneratePublic(OpenSSLRSAKeyFactory.java:47)
09-14 00:36:56.343: W/System.err(27217):    at java.security.KeyFactory.generatePublic(KeyFactory.java:171)
09-14 00:36:56.343: W/System.err(27217):    at com.probes.sm0ke.SmoKript.decodeKyFrom64(SmoKript.java:118)
09-14 00:36:56.343: W/System.err(27217):    at com.probes.sm0ke.GestureChooser.actOnChoose(GestureChooser.java:55)
09-14 00:36:56.343: W/System.err(27217):    at com.probes.sm0ke.GestureChooser.onGesturePerformed(GestureChooser.java:46)
09-14 00:36:56.343: W/System.err(27217):    at android.gesture.GestureOverlayView.fireOnGesturePerformed(GestureOverlayView.java:729)
09-14 00:36:56.343: W/System.err(27217):    at android.gesture.GestureOverlayView.access$400(GestureOverlayView.java:55)
09-14 00:36:56.343: W/System.err(27217):    at android.gesture.GestureOverlayView$FadeOutRunnable.run(GestureOverlayView.java:744)
09-14 00:36:56.353: W/System.err(27217):    at android.os.Handler.handleCallback(Handler.java:733)
09-14 00:36:56.353: W/System.err(27217):    at android.os.Handler.dispatchMessage(Handler.java:95)
09-14 00:36:56.353: W/System.err(27217):    at android.os.Looper.loop(Looper.java:136)
09-14 00:36:56.353: W/System.err(27217):    at android.app.ActivityThread.main(ActivityThread.java:5001)
09-14 00:36:56.353: W/System.err(27217):    at java.lang.reflect.Method.invokeNative(Native Method)
09-14 00:36:56.353: W/System.err(27217):    at java.lang.reflect.Method.invoke(Method.java:515)
09-14 00:36:56.353: W/System.err(27217):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
09-14 00:36:56.353: W/System.err(27217):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
09-14 00:36:56.353: W/System.err(27217):    at dalvik.system.NativeStart.main(Native Method)
09-14 00:36:56.353: W/System.err(27217): Caused by: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
09-14 00:36:56.353: W/System.err(27217):    at com.android.org.conscrypt.NativeCrypto.d2i_PUBKEY(Native Method)
09-14 00:36:56.353: W/System.err(27217):    at com.android.org.conscrypt.OpenSSLKey.getPublicKey(OpenSSLKey.java:99)
09-14 00:36:56.353: W/System.err(27217):    ... 17 more

我真的不知道为什么会这样。我在SQLite数据库中保存为私钥和公钥生成的Base64字符串。然后我从数据库中检索Base64字符串,解码它并尝试获取公钥。但它不起作用。任何人都可以帮我理解这个例外的原因吗?当我第一次尝试时,我将生成的Base64字符串直接传递给函数来解码它,只是为了尝试,它起作用了。但是如果我将它保存在数据库中然后让它解码,它就不再起作用了。

请帮帮我。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,试着这样做:

String pubKey = "your_modulus";
String exponent = "your_exponent";

byte[] keyBytes = Base64.decode(pubKey,Base64.DEFAULT);
byte[] exponentByte = Base64.decode(exponent,Base64.DEFAULT);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(keyBytes), new BigInteger(exponentByte));
RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);

请参阅:Android-Java RSA decrypt