RSA加密:Java和Android的区别

RSA加密:Java和Android的区别,java,android,encryption,rsa,public-key-encryption,Java,Android,Encryption,Rsa,Public Key Encryption,我使用RSA在Android上加密用户名和密码,并在服务器上解密(Tomcat6,Java1.6)。 Android加密: PublicKey pubKey = readPublicKeyFromFile(mod, ex); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); byte[] cipherData = cipher.doFinal(d

我使用RSA在Android上加密用户名和密码,并在服务器上解密(Tomcat6,Java1.6)。 Android加密:

    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解密:

    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部分(只是在一个main方法中),它可以正常工作。但不是在我的android(仿真器)中。在de服务器端,我收到以下错误:

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保持为bigInteger常量,这样就不会将它们写入文件。 我知道java1.6和java1.5加密之间有区别,所以都是用java1.6编译的

一些调试信息:

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

我做错了什么


谢谢

首先,看起来您正在使用公钥初始化两个密码。加密使用公钥,解密使用私钥。我希望这只是一个打字错误

我在RSA加密方面也遇到了很多麻烦,很多都是反复试验。我建议你试试其他供应商。我设法用BouncyCastle实现了RSA

Cipher wrapper = Cipher.getInstance("RSA", "BC");
wrapper.init(Cipher.ENCRYPT_MODE, publicKey);
encryptedData= wrapper.doFinal(unencryptedData);
尽管如此,我还是生成了自己的密钥对,因为这是一个会话加密

kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        KeyPair kp = kpg.genKeyPair();
        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();

我建议您使用特定的密码初始化:例如

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

这两方面都可以。由于桌面JVM和Android JVM之间的默认密码初始化填充似乎不同,因此出现了您正在获得的异常(BadPaddingException)。

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

我得到了这个确切的问题,到处阅读,部分是由于@Femi的回答,我找到了我需要的东西

解决方案是对密码使用以下算法规范:

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

这可以在Android和黑莓智能手机上进行加密。我知道这个问题已经问了四个月了,但以防其他人遇到这个问题。

可能的重复:你真的叫你私钥
publikey
?这真的是代码吗?或者只是从内存中输入问题?警告对于新协议,请尝试使用OAEP填充。PKCS#1容易受到oracle攻击。+1因为经过数小时的反复试验,我找到了这篇文章,它解决了我的问题。今天你救了我的命,谢谢:创建自己的密钥对是不安全的,因为需要为公钥建立信任。此外,指定提供者不是一种可移植的编码方式,默认的密钥算法可能会改变。只需指定完整的算法,包括填充模式(如其他答案中所述),就应该优先于此解决方案。为了确认,此解决方案在Android4.x和Java8中仍然有效。基本上,如果您使用Cipher.getInstance(“RSA”)它将不起作用,您需要指定更具体的一个。这在解密用JS加密的数据时也起作用。在我的例子中,使用Cipher.getInstance(“RSA”)而不使用“/ECB/PKCS1Padding”会在所需数据之前添加一些额外字符。谢谢。救了我