我正在使用RSA加密Android上的用户名和密码,并在服务器上解密它们(tomcat 6,java 1.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部分OUTSIDE 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包含十进制的模数和指数。
我做错了什么?
由于
答案 0 :(得分:42)
我在Android 2.2+中进行RSA加密,并在tomcat 6 java 1.6服务器上解密。
我得到了这个确切的问题,阅读了整个地方,部分归功于@Femi的回答,我遇到了我需要的东西。
解决方案是使用Cipher的以下算法规范:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
这适用于Android和BlackBerry智能手机的加密。我知道问题被问到已有四个月了,但万一其他人遇到了这个问题。
答案 1 :(得分:11)
我建议你使用特定的密码初始化:例如,
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
将同时适用于两者。您遇到的异常( BadPaddingException )正在发生,因为桌面JVM和Android JVM之间的默认密码初始化填充似乎不同。
答案 2 :(得分:1)
首先,看起来您正在使用公钥初始化两个密码。加密使用公钥,解密使用私钥。我希望这只是一个错字。
我在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();