RSA加密:Java和Android之间的区别

我正在使用RSA在Android上加密用户名和密码,并在服务器上解密它们(tomcat 6,java 1.6)。安卓加密:

    PublicKey pubKey = readPublicKeyFromFile(mod, ex);
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, pubKey);
    byte[] cipherData = cipher.doFinal(data);
    return cipherData;

Java Tomcat Decryption:

    PrivateKey pubKey = readPrivateKeyFromFile(mod, ex);
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, pubKey);
    byte[] cipherData = cipher.doFinal(data);
    return cipherData;

如果我在Android外部使用Android部分(只是在主要方法中),它工作正常。但不是在我的机器人(模拟器)里面。在服务器端,我收到以下错误:

javax.crypto.BadPaddingException: Blocktype mismatch: 0
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:311)
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:255)
    at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)

我将mod和ex保留为BigIntegers常量,因此我不会将它们写入文件中。我知道java1.6和java 1.5加密之间存在差异,因此两者都使用java 1.6编译。

一些调试信息:

在Android调试期间,我可以看到pubKey包含十六进制的模数和指数。如果我在main方法(同样是相同的代码)中调试,我可以看到pubKey包含十进制的模数和指数。

我做错了什么?

谢谢


答案 1

我在Android 2.2 +中进行RSA加密,并在tomcat 6 java 1.6服务器上解密。

我得到了这个确切的问题,到处阅读,部分感谢@Femi的答案,我遇到了我需要的东西。

解决方案是使用密码的 folowing 算法规范:

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

这适用于从Android和BlackBerry智能手机进行加密。我知道自从提出这个问题以来已经过去了四个月,但以防万一其他人遇到这个问题。


答案 2

我建议你使用特定的密码初始化:作为一个例子,

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

将同时适用于两者。您遇到的异常(BadPaddingException)正在发生,因为桌面 JVM 和 Android JVM 之间的默认密码初始化填充似乎不同。


推荐