本文介绍了RSA与Android环境之间的加密差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,对我即将发布的代码量表示歉意。我正在尝试使用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环境之间的加密差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 13:25