问题描述
首先,对我即将发布的代码量表示歉意。我正在尝试使用Java应用程序中的RSA公钥加密Android应用程序中的消息,然后将密文发送回Java环境进行解密,但是在尝试解密时,我总是收到以下错误: javax.crypto.BadPaddingException:解密错误
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
在com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
at com .sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
在javax.crypto.Cipher.doFinal(Cipher.java:2087)
...
密文确实包含正确的字节数(512),所以看到一个坏填充异常是令人困惑的。 SO的其他类似帖子已经建议使用RSA / ECB / PKCS1Padding作为算法,但这不起作用。
令人痛心的是,Android环境中的加密和解密(使用Base64.URL_SAFE作为'base64Type')工作正常,我似乎无法使用通过Java生成的公共密钥进行初始加密。
我已将最低限度的代码解压缩成示例,如下所示:
Android代码
private void exampleMethod(){
String messageString =为什么在Android中不起作用?
字符串serverPubKey = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoApIBIna77xq4j + M2RmyIhsB ++ 41NHcY4KIPfX4VP4ADnkO + 7ejbs4le / twrPtYGESVPF9czSMB5bzmTBZtq0jC8oT / 6wiDIBlSuzo4fBrGociBIuaOjyG / j3ZhpcWpWPXuzER + ehuQ + 8hZkMuJdK9IodqPR + 5jmCef4rXoKObwS02LYQ1co5dEmtZVQRmmeYaVnWibd / s1d4KKGvSzXap3YBTf8peH5UGIQrLOTqvX0bo34xFxmj5U0H3xudnnwuVAlQlj9KiHPPABuwNtm1buRKJb5HZhSCveyT / 2YAOmQqGrVN / nALtlZyTDZNs // Vp1zb9exSuG0t5xFc + pn4QIDAQAB;
String encryptedMessageString = getUrlEncodedCipherText(messageString,serverPubKey,Base64.NO_WRAP);
/ **
*的密文始终是相同的,并且不解密:DA_-RpCki-mjF6tSwiP2IhuW2UfPzZC7A9oVTTNptjT73HtROiQZvUC0Z2veJ5VwVx4toolvLErQmKKoQlqELSD756bu8ohEQwgJ4Xsu-3tXv-uEi5a9a_u19WnNLIF7tayDUhFeD2RzNvW895y1v-D30TvQRskNCFJfnjaytr_vmcVv8HrXURCmG6AMltaqdN72zh8p6VkKcjXSLiCApH957GXSqJCRzxbaQwf8X5EJfn8CQrPDGbE3gdhc2_hFwXQNIdxPxrOLtVbaFp9i_4GRWXJ6E2jHttV2bDv_uSVIz3OBzh7EkJiCnl3c904sH8QZae8c3SQyrTxVL7EpIA ,,
* /
}
public static String getUrlEncodedCipherText(String plainText,String pubKey,int base64Type){
try {
final PublicKey publicKey = loadPublicKey(pubKey,base64Type);
final byte [] cipherBytes = encrypt(plainText,publicKey);
String cipherText = base64Encode(cipherBytes,base64Type);
String urlEncodedCipherText = urlEncode(cipherText);
return urlEncodedCipherText;
}
catch(异常e){
e.printStackTrace();
返回null;
}
}
public static final String ALGORITHM =RSA;
public static PublicKey loadPublicKey(String stored,int base64Type)throws GeneralSecurityException {
String pubKey = stored.replace(BEGIN_PUBLIC_KEY,);
pubKey = pubKey.replace(END_PUBLIC_KEY,);
byte [] data = Base64.decode(pubKey,base64Type);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGORITHM);
PublicKey pub = fact.generatePublic(spec);
返回酒吧
}
public static byte [] encrypt(String text,PublicKey key){
byte [] cipherText = null;
try {
密码密码= Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,key);
cipherText = cipher.doFinal(text.getBytes());
}
catch(异常e){
e.printStackTrace();
}
return cipherText;
}
public static String base64Encode(byte [] cipherBytes,int base64Type){
byte [] base64Cipher = Base64.encode(cipherBytes,base64Type);
return new String(base64Cipher);
}
public static String urlEncode(String text){
return text.replace(+, - )。replace(/,_) .replace(=,,);
}
Java代码
私人无效exampleMethod(){
字符串PUBKEY =MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoApIBIna77xq4j + M2RmyIhsB ++ 41NHcY4KIPfX4VP4ADnkO + 7ejbs4le / twrPtYGESVPF9czSMB5bzmTBZtq0jC8oT / 6wiDIBlSuzo4fBrGociBIuaOjyG / j3ZhpcWpWPXuzER + ehuQ + 8hZkMuJdK9IodqPR + 5jmCef4rXoKObwS02LYQ1co5dEmtZVQRmmeYaVnWibd / s1d4KKGvSzXap3YBTf8peH5UGIQrLOTqvX0bo34xFxmj5U0H3xudnnwuVAlQlj9KiHPPABuwNtm1buRKJb5HZhSCveyT / 2YAOmQqGrVN / nALtlZyTDZNs // Vp1zb9exSuG0t5xFc + pn4QIDAQAB;
字符串的privKey =MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCgCkgEidrvvGriP4zZGbIiGwH77jU0dxjgog99fhU / gAOeQ77t6NuziV7 + 3C飞机+ 1gYRJU8X1zNIwHlvOZMFm2rSMLyhP / rCIMgGVK7Ojh8GsahyIEi5o6PIb + PdmGlxalY9e7MRH56G5D7yFmQy4l0r0ih2o9H7mOYJ5 / itego5vBLTYthDVyjl0Sa1lVBGaZ5hpWdaJt3 + zV3gooa9LNdqndgFN / yl4flQYhCss5Oq9fRujfjEXGaPlTQffG52efC5UCVCWP0qIc88AG7A22bVu5EolvkdmFIK97JP / ZgA6ZCoatU3 + cAu2VnJMNk2z / 9WnXNv17FK4bS3nEVz6mfhAgMBAAECggEBAIax4IchV0jqdbLR9cNK4yfdP0A / 7jun + SImg48FLPDy1xi + v9UQZMioV3F88FDEZPrNQdI45wrWI94 + wMS5V6BsMHYumOgGGxNo9m8WInrJz5GuJkdHuLMbqNZ6TlSMQOUiVUWWLSAuveOWgOJqriwRhsjDfBmbSBESUbP / wNdxX42RJudKJbVUV07urjFc3VAUrX + Sbj9KMZRe10pOzes7WKq9NMyQuitLcwCPzs2pQoXW1LdZYrVSi6MOqE1WHSL6VAgPx3cHYl7yznhspLmvDgnKTwnVbRo3BBwkxNbpvZXzgJBLEPLUtLqwNLKkU0aSF9MT5TABx4tfCaRQIiECgYEA70980I9mK74tjXlFrMKaLGigjHBss + Q / b7cRAtlQAhVOn0FCqz4Fc4iBri0iPekVIZ09lRehacEstTR8JBImMW2mqGyMwBbPaqQOf6xZ0pIoYb0ODAIjUNTWoBEr72 + ko5HjaoQbxeb2QGUhMe / t3M1CMsrETEQTdA + qNP5C61UCgYEAqzOL7sSsNfTYbAF156qPPqx1IyXNqu0wbKa / zufCxGlFJ DkaYoYIECKdLbpI2fqJsENqpZHgOnT0 + LbqhFn07NIe1zT / zf0rh7w5fqxqy3Srs4 + Mj6HwTIC7QpeXjiHxQuVrfi2W2ZatjQi8froxtEj3mpYKHsl0Ia89JSczQl0CgYAqHPXdCe8z8XK4u8esIE7bU8o1DK / EdH1JXpDqzG1NAIzmb6iY1ABHlZUknqKw / GyQjshAjXkFUE5a0RKrkloQRriWWQvn3dvAa4B1rVHdQYVDte5b5KBsYBgo8PynVSFG + 6xmmTr996gMKv / NduiH + 8MThyVGOpCl0v / j9X63RQKBgEmOhir6eXtdTbdqETyOPamR82o8jddIvauRIYxGa5p0GG7t0fZO3BwCo0HIbhCp4orHDIVC3fJ / 2dkazjw7Yk52ISYZ8WaRxig1qQZSEjiEUll97ciwrUxRayO7ejRpRP2XEM5PzCaE5OBZxpM0cLKjPy8 + E + 8SY0Etx7m01ANJAoGBALUubgeKx1fut80YHLDmxOiTg9olFJi83Lj1TPQ0fRCXdJX6pHCSypBScoXuJYVwuIavHhTf8DPQ6OONq / V3DXKsGLydK / 2E5yg + bz3qYfYslb3vDkZovNJDmfoyR0XakWbUTotntUQqodLk8Q9klHKp6oy + MkGY57R5OhIZBGPa;
String message =为什么在Android中不起作用?;
String encryptedMessage = getUrlEncodedCipherText(message,pubKey);
try {
byte [] base64Decoded = Base64.decodeBase64(encryptedMessage.getBytes(Charset.forName(UTF-8)));
String decryptptedMessage = decrypt(base64Decoded,loadPrivateKey(privKey));
System.out.println(decryptptedMessage:+ decryptptedMessage);
/ **
*这个工程!密码总是按预期的方式出来,并成功解码。
* /
}
catch(异常e){
e.printStackTrace();
}
}
public static String getUrlEncodedCipherText(String plainText,String pubKey){
try {
final PublicKey publicKey = loadPublicKey(pubKey);
final byte [] cipherBytes = encrypt(plainText,publicKey);
String cipherText = base64Encode(cipherBytes);
String urlEncodedCipherText = urlEncode(cipherText);
return urlEncodedCipherText;
}
catch(异常e){
e.printStackTrace();
返回null;
}
}
public static final String ALGORITHM =RSA;
public static PublicKey loadPublicKey(String stored)throws GeneralSecurityException {
String pubKey = stored.replace(BEGIN_PUBLIC_KEY,);
pubKey = pubKey.replace(END_PUBLIC_KEY,);
byte [] data = Base64.decodeBase64(pubKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGORITHM);
PublicKey pub = fact.generatePublic(spec);
返回酒吧
}
public static byte [] encrypt(String text,PublicKey key){
byte [] cipherText = null;
try {
密码密码= Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,key);
cipherText = cipher.doFinal(text.getBytes());
}
catch(异常e){
e.printStackTrace();
}
return cipherText;
}
public static String decrypt(byte [] encrypted,PrivateKey key){
byte [] decryptptedText = null;
try {
final Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE,key);
decryptptedText = cipher.doFinal(encrypted);
}
catch(异常e){
e.printStackTrace();
返回null;
}
return new String(decryptptedText);
}
public static String base64Encode(byte [] cipherBytes){
byte [] base64Cipher = Base64.encodeBase64(cipherBytes);
return new String(base64Cipher);
}
public static String urlEncode(String text){
return text.replace(+, - )。replace(/,_) .replace(=,,);
}
我知道问题必须与方式Android和Java解释RSA算法,和/或与Base64编码/解码的差异,但我被困扰。非常感谢任何帮助。
解决了!问题是我使用相同的ALGORITHM字符串进行密码,KeyFactory等。我把它分成两个不同的字符串,我的问题的完整解决方案是...
Android代码
private void exampleMethod(){
String messageString =这实际上在Java和Android! ;
字符串serverPubKey = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjS7T3WJ + VLucnUP5WYryeg + hhOjZZl5VxwvJAgo4GrXaXdernTPtmXnOSUlbhd928QRCip7D3rLwJNvGIwhPa6coA + YQnj + aHQC02AvCJP / 9jpeNmm5MASZfYFXrdmOrMhAPpDZ4rUk1mqtvpwBkYmW3VbMtG336wT1bAIKPHCZuI2n6glupJvs8gK0NuIoAPRlxiQmQD7NCcRx1Et4JmqOMIRC + HqdGv9GGqC / 0PB0Fv6LXi8GdzJQPMdoRLR0rvVykNeIzmcimejoIVjI78XUZeB1hF7p55h6W4C4Xm / PrnzKuXw4lBVehZtRhyIvNO62G / eNEZ3tup1 /米+ vkzHQIDAQAB;
String encryptedMessageString = getUrlEncodedCipherText(messageString,serverPubKey,Base64.NO_WRAP);
System.out.println(encryptedMessageString:+ encryptedMessageString);
/ **
*这个工程!密码总是按预期的方式出来,并在进入Java应用程序时成功解码。
* /
}
public static String getUrlEncodedCipherText(String plainText,String pubKey,int base64Type){
try {
final PublicKey publicKey = loadPublicKey pubKey,base64Type);
final byte [] cipherBytes = encrypt(plainText,publicKey);
String cipherText = base64Encode(cipherBytes,base64Type);
String urlEncodedCipherText = urlEncode(cipherText);
return urlEncodedCipherText;
}
catch(异常e){
e.printStackTrace();
返回null;
}
}
public static final String ALGORITHM =RSA;
public static final String CIPHER_ALGORITHM =RSA / ECB / PKCS1Padding;
public static PublicKey loadPublicKey(String stored,int base64Type)throws GeneralSecurityException {
String pubKey = stored.replace(BEGIN_PUBLIC_KEY,);
pubKey = pubKey.replace(END_PUBLIC_KEY,);
byte [] data = Base64.decode(pubKey,base64Type);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGORITHM);
PublicKey pub = fact.generatePublic(spec);
返回酒吧
}
public static byte [] encrypt(String text,PublicKey key){
byte [] cipherText = null;
try {
密码密码= Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,key);
cipherText = cipher.doFinal(text.getBytes());
}
catch(异常e){
e.printStackTrace();
}
return cipherText;
}
public static String base64Encode(byte [] cipherBytes,int base64Type){
byte [] base64Cipher = Base64.encode(cipherBytes,base64Type);
return new String(base64Cipher);
}
public static String urlEncode(String text){
return text.replace(+, - )。replace(/,_) .replace(=,,);
}
Java代码
私人无效exampleMethod(){
字符串PUBKEY = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjS7T3WJ + VLucnUP5WYryeg + hhOjZZl5VxwvJAgo4GrXaXdernTPtmXnOSUlbhd928QRCip7D3rLwJNvGIwhPa6coA + YQnj + aHQC02AvCJP / 9jpeNmm5MASZfYFXrdmOrMhAPpDZ4rUk1mqtvpwBkYmW3VbMtG336wT1bAIKPHCZuI2n6glupJvs8gK0NuIoAPRlxiQmQD7NCcRx1Et4JmqOMIRC + HqdGv9GGqC / 0PB0Fv6LXi8GdzJQPMdoRLR0rvVykNeIzmcimejoIVjI78XUZeB1hF7p55h6W4C4Xm / PrnzKuXw4lBVehZtRhyIvNO62G / eNEZ3tup1 /米+ vkzHQIDAQAB;
字符串的privKey =MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCNLtPdYn5Uu5ydQ / lZivJ6D6GE6NlmXlXHC8kCCjgatdpd16udM + 2Zec5JSVuF33bxBEKKnsPesvAk28YjCE9rpygD5hCeP5odALTYC8Ik // 2Ol42abkwBJl9gVet2Y6syEA + kNnitSTWaq2 + nAGRiZbdVsy0bffrBPVsAgo8cJm4jafqCW6km + zyArQ24igA9GXGJCZAPs0JxHHUS3gmao4whEL4ep0a / 0YaoL / Q8HQW / oteLwZ3MlA8x2hEtHSu9XKQ14jOZyKZ6OghWMjvxdRl4HWEXunnmHpbgLheb8 + ufMq5fDiUFV6Fm1GHIi807rYb940Rne26nX + B6 + TMdAgMBAAECggEAOHrlUwmWFHvBmcCZvlKx0lbyfONSJXvTwP9b + K7x5u2dYDFpfEhL4zwxZGwuaw4M3TqhDCeboDnhjD1HtLgcXarPfU / KkiRLmRKxRkTd9ENcwnCqu38odMVPHpEA06nn0O1P9Je + C0TgZvHyhtLHVf3vLB + 0Ce2KJUhQYZHZgp7dBt0jgsGlEvQTtc1q3UtElNYbcPdLhg16Dcvw93 + C + + CWizUxHKl2VAxYBz5fGBxa + Cc6xbj4OGd0mvK9Z 71cX8sgp + WIdSV3a2SZrwYq8XxdtJJfdOwPc6LE56Ul9y3fE / biG8DM8ysu7g4C2K1tjKBTq1Rzz4NBCaGwkWQwGQKBgQDCX5nOiHYi0OYoE3WEVYVuEaf / YljurMiU4xYsy3bXzI42S + iKfVHz + / + tvTrXSE0n6AdJnDHyP7mncFZodaurYR90S9VW3P + aOGoysmOmBRWW30xyIZ1g5 PJ9xPzoBfyc / AGHO5w5roY7Gg5myUC + UbucFU + 9 / JHUVoGV8yFz + wKBgQC58f8iY37sXf / sguv0YHpUV1suPWT90kxC25eRQz0lHWIIw 4gfGXI7Tf2vtx7hUPK1z3X9lPiTsqmZIRKPrvykD8djmpfZEOzZlLxxhHUZMZppx19xSsgHaespCZir68aytBWn7FOVpehJP7MWaJurg03V8Cv0NSPU5JhN / j8xxwKBgQCkb6I78oAWtilvz / 6EJKGL244HZJkd2bibFH4HCV4R9HB / CLrCpoB1a0BsCueQwFa + FVp9aTfbv / N4iCHoLzJcJHeneTu5mmqe32ERBw / MF / yUhhnGX79o0 + 25brQSSjZKTHuyf0CMH9RZHZL / a9TE7XpM8k6SyKBKRaC9TYGIjwKBgDZG10x4coIYZi3pgWqSBuM7pJf4v9P / YNdbNgDm + aAt1YHtYXyCdv + solJ6R39Jm69KYYylwXGLg0n5h2t9jq1tFayTYaOw9xIEAoW4Pl4eRo597fQp + f2AA261KGV2q0danb + okjVqekV3XJU778S + zSeXtZzRLiZkm7iYcGXdAoGAUEbRAsopG + blDBmuC5Fhr7Grof9lw / zRgfl516n9oujOmDY8Sl4F7jHkgKzOL1CpvMbRswr6G3tmpJMYGNy0HVX4n4QAiIvEraLUtLlh7LotUiU8zzjniK7HPANoOsQxEi6iUR6jWRf0LKgckE9aaUJjvljj1Hr4PbFpny2gjD4 =;
String message =这实际上适用于Java和Android!;
String encryptedMessage = getUrlEncodedCipherText(message,pubKey);
try {
byte [] base64Decoded = Base64.decodeBase64(encryptedMessage.getBytes(Charset.forName(UTF-8)));
String decryptptedMessage = decrypt(base64Decoded,loadPrivateKey(privKey));
System.out.println(decryptptedMessage:+ decryptptedMessage);
/ **
*这个工程!密码总是按预期的方式出来,并成功解码。
* /
}
catch(异常e){
e.printStackTrace();
}
}
public static String getUrlEncodedCipherText(String plainText,String pubKey){
try {
final PublicKey publicKey = loadPublicKey(pubKey);
final byte [] cipherBytes = encrypt(plainText,publicKey);
String cipherText = base64Encode(cipherBytes);
String urlEncodedCipherText = urlEncode(cipherText);
return urlEncodedCipherText;
}
catch(异常e){
e.printStackTrace();
返回null;
}
}
public static final String ALGORITHM =RSA;
public static final String CIPHER_ALGORITHM =RSA / ECB / PKCS1Padding;
public static PublicKey loadPublicKey(String stored)throws GeneralSecurityException {
String pubKey = stored.replace(BEGIN_PUBLIC_KEY,);
pubKey = pubKey.replace(END_PUBLIC_KEY,);
byte [] data = Base64.decodeBase64(pubKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGORITHM);
PublicKey pub = fact.generatePublic(spec);
返回酒吧
}
public static byte [] encrypt(String text,PublicKey key){
byte [] cipherText = null;
try {
密码密码= Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,key);
cipherText = cipher.doFinal(text.getBytes());
}
catch(异常e){
e.printStackTrace();
}
return cipherText;
}
public static String decrypt(byte [] encrypted,PrivateKey key){
byte [] decryptptedText = null;
try {
final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE,key);
decryptptedText = cipher.doFinal(encrypted);
}
catch(异常e){
e.printStackTrace();
返回null;
}
return new String(decryptptedText);
}
public static String base64Encode(byte [] cipherBytes){
byte [] base64Cipher = Base64.encodeBase64(cipherBytes);
return new String(base64Cipher);
}
public static String urlEncode(String text){
return text.replace(+, - )。replace(/,_) .replace(=,,);
}
Firstly, apologies for the amount of code I'm about to post. I'm trying to use the RSA public key from my Java application to encrypt a message in an Android app, and then send the ciphertext back to a Java environment for decryption, but upon attempting to decrypt I always get this error:
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
...
The ciphertext does contain the correct number of bytes (512), so it's confusing to see a "bad padding" exception. Other similar posts on SO have suggested using "RSA/ECB/PKCS1Padding" as the algorithm, but this does not work.
Annoyingly, encryption and decryption in the Android environment (using Base64.URL_SAFE as the 'base64Type') works just fine, I just can't seem to get the initial encryption working with the public key produced via Java.
I have extracted the bare minimum code into examples, as shown below:
Android Code
private void exampleMethod(){
String messageString = "Why does this not work in Android?";
String serverPubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoApIBIna77xq4j+M2RmyIhsB++41NHcY4KIPfX4VP4ADnkO+7ejbs4le/twrPtYGESVPF9czSMB5bzmTBZtq0jC8oT/6wiDIBlSuzo4fBrGociBIuaOjyG/j3ZhpcWpWPXuzER+ehuQ+8hZkMuJdK9IodqPR+5jmCef4rXoKObwS02LYQ1co5dEmtZVQRmmeYaVnWibd/s1d4KKGvSzXap3YBTf8peH5UGIQrLOTqvX0bo34xFxmj5U0H3xudnnwuVAlQlj9KiHPPABuwNtm1buRKJb5HZhSCveyT/2YAOmQqGrVN/nALtlZyTDZNs//Vp1zb9exSuG0t5xFc+pn4QIDAQAB";
String encryptedMessageString = getUrlEncodedCipherText(messageString, serverPubKey, Base64.NO_WRAP);
/**
* CipherText is ALWAYS the same and does not decrypt: DA_-RpCki-mjF6tSwiP2IhuW2UfPzZC7A9oVTTNptjT73HtROiQZvUC0Z2veJ5VwVx4toolvLErQmKKoQlqELSD756bu8ohEQwgJ4Xsu-3tXv-uEi5a9a_u19WnNLIF7tayDUhFeD2RzNvW895y1v-D30TvQRskNCFJfnjaytr_vmcVv8HrXURCmG6AMltaqdN72zh8p6VkKcjXSLiCApH957GXSqJCRzxbaQwf8X5EJfn8CQrPDGbE3gdhc2_hFwXQNIdxPxrOLtVbaFp9i_4GRWXJ6E2jHttV2bDv_uSVIz3OBzh7EkJiCnl3c904sH8QZae8c3SQyrTxVL7EpIA,,
*/
}
public static String getUrlEncodedCipherText(String plainText, String pubKey, int base64Type){
try {
final PublicKey publicKey = loadPublicKey(pubKey, base64Type);
final byte[] cipherBytes = encrypt(plainText, publicKey);
String cipherText = base64Encode(cipherBytes, base64Type);
String urlEncodedCipherText = urlEncode(cipherText);
return urlEncodedCipherText;
}
catch (Exception e){
e.printStackTrace();
return null;
}
}
public static final String ALGORITHM = "RSA";
public static PublicKey loadPublicKey(String stored, int base64Type) throws GeneralSecurityException {
String pubKey = stored.replace(BEGIN_PUBLIC_KEY, "");
pubKey = pubKey.replace(END_PUBLIC_KEY, "");
byte[] data = Base64.decode(pubKey, base64Type);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGORITHM);
PublicKey pub = fact.generatePublic(spec);
return pub;
}
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
}
catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
public static String base64Encode(byte[] cipherBytes, int base64Type){
byte[] base64Cipher = Base64.encode(cipherBytes, base64Type);
return new String(base64Cipher);
}
public static String urlEncode(String text){
return text.replace("+", "-").replace("/", "_").replace("=", ",");
}
Java Code
private void exampleMethod(){
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoApIBIna77xq4j+M2RmyIhsB++41NHcY4KIPfX4VP4ADnkO+7ejbs4le/twrPtYGESVPF9czSMB5bzmTBZtq0jC8oT/6wiDIBlSuzo4fBrGociBIuaOjyG/j3ZhpcWpWPXuzER+ehuQ+8hZkMuJdK9IodqPR+5jmCef4rXoKObwS02LYQ1co5dEmtZVQRmmeYaVnWibd/s1d4KKGvSzXap3YBTf8peH5UGIQrLOTqvX0bo34xFxmj5U0H3xudnnwuVAlQlj9KiHPPABuwNtm1buRKJb5HZhSCveyT/2YAOmQqGrVN/nALtlZyTDZNs//Vp1zb9exSuG0t5xFc+pn4QIDAQAB";
String privKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCgCkgEidrvvGriP4zZGbIiGwH77jU0dxjgog99fhU/gAOeQ77t6NuziV7+3Cs+1gYRJU8X1zNIwHlvOZMFm2rSMLyhP/rCIMgGVK7Ojh8GsahyIEi5o6PIb+PdmGlxalY9e7MRH56G5D7yFmQy4l0r0ih2o9H7mOYJ5/itego5vBLTYthDVyjl0Sa1lVBGaZ5hpWdaJt3+zV3gooa9LNdqndgFN/yl4flQYhCss5Oq9fRujfjEXGaPlTQffG52efC5UCVCWP0qIc88AG7A22bVu5EolvkdmFIK97JP/ZgA6ZCoatU3+cAu2VnJMNk2z/9WnXNv17FK4bS3nEVz6mfhAgMBAAECggEBAIax4IchV0jqdbLR9cNK4yfdP0A/7jun+SImg48FLPDy1xi+v9UQZMioV3F88FDEZPrNQdI45wrWI94+wMS5V6BsMHYumOgGGxNo9m8WInrJz5GuJkdHuLMbqNZ6TlSMQOUiVUWWLSAuveOWgOJqriwRhsjDfBmbSBESUbP/wNdxX42RJudKJbVUV07urjFc3VAUrX+Sbj9KMZRe10pOzes7WKq9NMyQuitLcwCPzs2pQoXW1LdZYrVSi6MOqE1WHSL6VAgPx3cHYl7yznhspLmvDgnKTwnVbRo3BBwkxNbpvZXzgJBLEPLUtLqwNLKkU0aSF9MT5TABx4tfCaRQIiECgYEA70980I9mK74tjXlFrMKaLGigjHBss+Q/b7cRAtlQAhVOn0FCqz4Fc4iBri0iPekVIZ09lRehacEstTR8JBImMW2mqGyMwBbPaqQOf6xZ0pIoYb0ODAIjUNTWoBEr72+ko5HjaoQbxeb2QGUhMe/t3M1CMsrETEQTdA+qNP5C61UCgYEAqzOL7sSsNfTYbAF156qPPqx1IyXNqu0wbKa/zufCxGlFJDkaYoYIECKdLbpI2fqJsENqpZHgOnT0+LbqhFn07NIe1zT/zf0rh7w5fqxqy3Srs4+Mj6HwTIC7QpeXjiHxQuVrfi2W2ZatjQi8froxtEj3mpYKHsl0Ia89JSczQl0CgYAqHPXdCe8z8XK4u8esIE7bU8o1DK/EdH1JXpDqzG1NAIzmb6iY1ABHlZUknqKw/GyQjshAjXkFUE5a0RKrkloQRriWWQvn3dvAa4B1rVHdQYVDte5b5KBsYBgo8PynVSFG+6xmmTr996gMKv/NduiH+8MThyVGOpCl0v/j9X63RQKBgEmOhir6eXtdTbdqETyOPamR82o8jddIvauRIYxGa5p0GG7t0fZO3BwCo0HIbhCp4orHDIVC3fJ/2dkazjw7Yk52ISYZ8WaRxig1qQZSEjiEUll97ciwrUxRayO7ejRpRP2XEM5PzCaE5OBZxpM0cLKjPy8+E+8SY0Etx7m01ANJAoGBALUubgeKx1fut80YHLDmxOiTg9olFJi83Lj1TPQ0fRCXdJX6pHCSypBScoXuJYVwuIavHhTf8DPQ6OONq/V3DXKsGLydK/2E5yg+bz3qYfYslb3vDkZovNJDmfoyR0XakWbUTotntUQqodLk8Q9klHKp6oy+MkGY57R5OhIZBGPa";
String message = "Why does this not work in Android?";
String encryptedMessage = getUrlEncodedCipherText(message, pubKey);
try {
byte[] base64Decoded = Base64.decodeBase64(encryptedMessage.getBytes(Charset.forName("UTF-8")));
String decryptedMessage = decrypt(base64Decoded, loadPrivateKey(privKey));
System.out.println("decryptedMessage: " + decryptedMessage);
/**
* This works! Ciphertext always comes out different, as expected, and decodes successfully.
*/
}
catch (Exception e){
e.printStackTrace();
}
}
public static String getUrlEncodedCipherText(String plainText, String pubKey){
try {
final PublicKey publicKey = loadPublicKey(pubKey);
final byte[] cipherBytes = encrypt(plainText, publicKey);
String cipherText = base64Encode(cipherBytes);
String urlEncodedCipherText = urlEncode(cipherText);
return urlEncodedCipherText;
}
catch (Exception e){
e.printStackTrace();
return null;
}
}
public static final String ALGORITHM = "RSA";
public static PublicKey loadPublicKey(String stored) throws GeneralSecurityException {
String pubKey = stored.replace(BEGIN_PUBLIC_KEY, "");
pubKey = pubKey.replace(END_PUBLIC_KEY, "");
byte[] data = Base64.decodeBase64(pubKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGORITHM);
PublicKey pub = fact.generatePublic(spec);
return pub;
}
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
}
catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
public static String decrypt(byte[] encrypted, PrivateKey key) {
byte[] decryptedText = null;
try {
final Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
decryptedText = cipher.doFinal(encrypted);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
return new String(decryptedText);
}
public static String base64Encode(byte[] cipherBytes){
byte[] base64Cipher = Base64.encodeBase64(cipherBytes);
return new String(base64Cipher);
}
public static String urlEncode(String text){
return text.replace("+", "-").replace("/", "_").replace("=", ",");
}
I'm aware that the problem has to be to do with difference in the way Android and Java interpret the RSA algorithm, and/or differences with the Base64 encode/decode, but I'm stumped. Any assistance greatly appreciated.
Solved it! The issue was that I was using the same ALGORITHM String for Cipher, KeyFactory etc. I split this into two different Strings, and the full solution for my problem is...
Android Code
private void exampleMethod(){
String messageString = "This actually works in Java AND Android!";
String serverPubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjS7T3WJ+VLucnUP5WYryeg+hhOjZZl5VxwvJAgo4GrXaXdernTPtmXnOSUlbhd928QRCip7D3rLwJNvGIwhPa6coA+YQnj+aHQC02AvCJP/9jpeNmm5MASZfYFXrdmOrMhAPpDZ4rUk1mqtvpwBkYmW3VbMtG336wT1bAIKPHCZuI2n6glupJvs8gK0NuIoAPRlxiQmQD7NCcRx1Et4JmqOMIRC+HqdGv9GGqC/0PB0Fv6LXi8GdzJQPMdoRLR0rvVykNeIzmcimejoIVjI78XUZeB1hF7p55h6W4C4Xm/PrnzKuXw4lBVehZtRhyIvNO62G/eNEZ3tup1/m+vkzHQIDAQAB";
String encryptedMessageString = getUrlEncodedCipherText(messageString, serverPubKey, Base64.NO_WRAP);
System.out.println("encryptedMessageString: " + encryptedMessageString);
/**
* This works! Ciphertext always comes out different, as expected, and decodes successfully when fed into Java application.
*/
}
public static String getUrlEncodedCipherText(String plainText, String pubKey, int base64Type){
try {
final PublicKey publicKey = loadPublicKey(pubKey, base64Type);
final byte[] cipherBytes = encrypt(plainText, publicKey);
String cipherText = base64Encode(cipherBytes, base64Type);
String urlEncodedCipherText = urlEncode(cipherText);
return urlEncodedCipherText;
}
catch (Exception e){
e.printStackTrace();
return null;
}
}
public static final String ALGORITHM = "RSA";
public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
public static PublicKey loadPublicKey(String stored, int base64Type) throws GeneralSecurityException {
String pubKey = stored.replace(BEGIN_PUBLIC_KEY, "");
pubKey = pubKey.replace(END_PUBLIC_KEY, "");
byte[] data = Base64.decode(pubKey, base64Type);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGORITHM);
PublicKey pub = fact.generatePublic(spec);
return pub;
}
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
}
catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
public static String base64Encode(byte[] cipherBytes, int base64Type){
byte[] base64Cipher = Base64.encode(cipherBytes, base64Type);
return new String(base64Cipher);
}
public static String urlEncode(String text){
return text.replace("+", "-").replace("/", "_").replace("=", ",");
}
Java Code
private void exampleMethod(){
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjS7T3WJ+VLucnUP5WYryeg+hhOjZZl5VxwvJAgo4GrXaXdernTPtmXnOSUlbhd928QRCip7D3rLwJNvGIwhPa6coA+YQnj+aHQC02AvCJP/9jpeNmm5MASZfYFXrdmOrMhAPpDZ4rUk1mqtvpwBkYmW3VbMtG336wT1bAIKPHCZuI2n6glupJvs8gK0NuIoAPRlxiQmQD7NCcRx1Et4JmqOMIRC+HqdGv9GGqC/0PB0Fv6LXi8GdzJQPMdoRLR0rvVykNeIzmcimejoIVjI78XUZeB1hF7p55h6W4C4Xm/PrnzKuXw4lBVehZtRhyIvNO62G/eNEZ3tup1/m+vkzHQIDAQAB";
String privKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCNLtPdYn5Uu5ydQ/lZivJ6D6GE6NlmXlXHC8kCCjgatdpd16udM+2Zec5JSVuF33bxBEKKnsPesvAk28YjCE9rpygD5hCeP5odALTYC8Ik//2Ol42abkwBJl9gVet2Y6syEA+kNnitSTWaq2+nAGRiZbdVsy0bffrBPVsAgo8cJm4jafqCW6km+zyArQ24igA9GXGJCZAPs0JxHHUS3gmao4whEL4ep0a/0YaoL/Q8HQW/oteLwZ3MlA8x2hEtHSu9XKQ14jOZyKZ6OghWMjvxdRl4HWEXunnmHpbgLheb8+ufMq5fDiUFV6Fm1GHIi807rYb940Rne26nX+b6+TMdAgMBAAECggEAOHrlUwmWFHvBmcCZvlKx0lbyfONSJXvTwP9b+K7x5u2dYDFpfEhL4zwxZGwuaw4M3TqhDCeboDnhjD1HtLgcXarPfU/KkiRLmRKxRkTd9ENcwnCqu38odMVPHpEA06nn0O1P9Je+C0TgZvHyhtLHVf3vLB+0Ce2KJUhQYZHZgp7dBt0jgsGlEvQTtc1q3UtElNYbcPdLhg16Dcvw93+C+CWizUxHKl2VAxYBz5fGBxa+Cc6xbj4OGd0mvK9Z+71cX8sgp+WIdSV3a2SZrwYq8XxdtJJfdOwPc6LE56Ul9y3fE/biG8DM8ysu7g4C2K1tjKBTq1Rzz4NBCaGwkWQwGQKBgQDCX5nOiHYi0OYoE3WEVYVuEaf/YljurMiU4xYsy3bXzI42S+iKfVHz+/tvTrXSE0n6AdJnDHyP7mncFZodaurYR90S9VW3P+aOGoysmOmBRWW30xyIZ1g5+PJ9xPzoBfyc/AGHO5w5roY7Gg5myUC+UbucFU+9/JHUVoGV8yFz+wKBgQC58f8iY37sXf/sguv0YHpUV1suPWT90kxC25eRQz0lHWIIw4gfGXI7Tf2vtx7hUPK1z3X9lPiTsqmZIRKPrvykD8djmpfZEOzZlLxxhHUZMZppx19xSsgHaespCZir68aytBWn7FOVpehJP7MWaJurg03V8Cv0NSPU5JhN/j8xxwKBgQCkb6I78oAWtilvz/6EJKGL244HZJkd2bibFH4HCV4R9HB/CLrCpoB1a0BsCueQwFa+FVp9aTfbv/N4iCHoLzJcJHeneTu5mmqe32ERBw/MF/yUhhnGX79o0+25brQSSjZKTHuyf0CMH9RZHZL/a9TE7XpM8k6SyKBKRaC9TYGIjwKBgDZG10x4coIYZi3pgWqSBuM7pJf4v9P/YNdbNgDm+aAt1YHtYXyCdv+solJ6R39Jm69KYYylwXGLg0n5h2t9jq1tFayTYaOw9xIEAoW4Pl4eRo597fQp+f2AA261KGV2q0danb+okjVqekV3XJU778S+zSeXtZzRLiZkm7iYcGXdAoGAUEbRAsopG+blDBmuC5Fhr7Grof9lw/zRgfl516n9oujOmDY8Sl4F7jHkgKzOL1CpvMbRswr6G3tmpJMYGNy0HVX4n4QAiIvEraLUtLlh7LotUiU8zzjniK7HPANoOsQxEi6iUR6jWRf0LKgckE9aaUJjvljj1Hr4PbFpny2gjD4=";
String message = "This actually works in Java AND Android!";
String encryptedMessage = getUrlEncodedCipherText(message, pubKey);
try {
byte[] base64Decoded = Base64.decodeBase64(encryptedMessage.getBytes(Charset.forName("UTF-8")));
String decryptedMessage = decrypt(base64Decoded, loadPrivateKey(privKey));
System.out.println("decryptedMessage: " + decryptedMessage);
/**
* This works! Ciphertext always comes out different, as expected, and decodes successfully.
*/
}
catch (Exception e){
e.printStackTrace();
}
}
public static String getUrlEncodedCipherText(String plainText, String pubKey){
try {
final PublicKey publicKey = loadPublicKey(pubKey);
final byte[] cipherBytes = encrypt(plainText, publicKey);
String cipherText = base64Encode(cipherBytes);
String urlEncodedCipherText = urlEncode(cipherText);
return urlEncodedCipherText;
}
catch (Exception e){
e.printStackTrace();
return null;
}
}
public static final String ALGORITHM = "RSA";
public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
public static PublicKey loadPublicKey(String stored) throws GeneralSecurityException {
String pubKey = stored.replace(BEGIN_PUBLIC_KEY, "");
pubKey = pubKey.replace(END_PUBLIC_KEY, "");
byte[] data = Base64.decodeBase64(pubKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGORITHM);
PublicKey pub = fact.generatePublic(spec);
return pub;
}
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
}
catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
public static String decrypt(byte[] encrypted, PrivateKey key) {
byte[] decryptedText = null;
try {
final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
decryptedText = cipher.doFinal(encrypted);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
return new String(decryptedText);
}
public static String base64Encode(byte[] cipherBytes){
byte[] base64Cipher = Base64.encodeBase64(cipherBytes);
return new String(base64Cipher);
}
public static String urlEncode(String text){
return text.replace("+", "-").replace("/", "_").replace("=", ",");
}
这篇关于RSA与Android环境之间的加密差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!