2013-03-15 97 views
0

public_key.der的加密工作完美无缺,但public_key.der解密不。用Java解密的base64_encoded String是通过openssl通过我的服务器private_key.pem生成的。进行RSA解密时出错

我得到一个LogCat错误:RSA块的数据太多。我敢肯定情况并非如此,因为我的private_key.pem加密数据是文本“hello”。

这里是我的MainActivity.class(应该是相当类似Java解密)

public class Main extends Activity { 

    // Decrypt tester 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     String plainText = "hello"; 
     // Base64 Encoded 
     String encryptedText = "SWfL6wpS87SsvByIfLO1W5Gg/gOMqtplNtqBrDELfQav0ipCy0BddHpTlmlgQO+6HRY2JWsw6hp5rlmmBJG722Ujc4Rm5MZr8BbKWMgX89rvmvUG/YeswTjHZsrzbx6k6krChM55dsJCU3JSXPMIcTTgRxVValgLeCfX1SwoOpNZ2m4WQAhX6NrSYwSXGLUHfrguQogTpU5wEcDQ0HR4vBlQO5fU8z2MwoP50Vs8f+4EysEwSy9ezsYHWDtW8M9t3EuF8Roq++/Y8GLASrYZxuAA0IPHGvR9Qufa04i7HlAAsDu9LQuOGUf35KkpFoCx0XyuA0qppccGdqHuK5IIoQ=="; 
     try { 
      String encrypted = encrypt(getAssets().open("public_key.der"), plainText); 
      Log.d("Encrypted", encrypted); 
      // Returns a base64 encoded string. 

      Log.d("TAG", "Decryption start"); 

      String decrypted = decrypt(getAssets().open("public_key.der"), encryptedText); 
      Log.d("Decrypted", decrypted); 
     } catch (Exception e) { 
      Log.e("TEST", Log.getStackTraceString(e)); 
     } 
    } 

    public static String encrypt(InputStream stream, String plaintext) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, 
      NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 

     byte[] encodedKey = new byte[stream.available()]; 
     stream.read(encodedKey); 
     X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); 
     KeyFactory kf = KeyFactory.getInstance("RSA"); 
     PublicKey pkPublic = kf.generatePublic(publicKeySpec); 

     Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 
     pkCipher.init(Cipher.ENCRYPT_MODE, pkPublic); 
     byte[] encryptedInByte = pkCipher.doFinal(plaintext.getBytes()); 

     String encryptedInString = new String(Base64Coder.encode(encryptedInByte)); 

     return encryptedInString; 
    } 

    public static String decrypt(InputStream stream, String encrypted) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, 
      NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 

     byte[] encodedKey = new byte[stream.available()]; 
     stream.read(encodedKey); 
     X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); 
     KeyFactory kf = KeyFactory.getInstance("RSA"); 
     PublicKey pkPublic = kf.generatePublic(publicKeySpec); 

     Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 
     pkCipher.init(Cipher.DECRYPT_MODE, pkPublic); 
     byte[] decryptedInByte = pkCipher.doFinal(encrypted.getBytes()); 
     String decryptedInString = new String(Base64Coder.encode(decryptedInByte)); 
     return decryptedInString; 
    } 
} 

这里是我的Base64Decoder

public class Base64Coder { 

    private static char[] map1 = new char[64]; 
    static { 
     int i = 0; 
     for (char c = 'A'; c <= 'Z'; c++) 
      map1[i++] = c; 
     for (char c = 'a'; c <= 'z'; c++) 
      map1[i++] = c; 
     for (char c = '0'; c <= '9'; c++) 
      map1[i++] = c; 
     map1[i++] = '+'; 
     map1[i++] = '/'; 
    } 

    private static byte[] map2 = new byte[128]; 
    static { 
     for (int i = 0; i < map2.length; i++) 
      map2[i] = -1; 
     for (int i = 0; i < 64; i++) 
      map2[map1[i]] = (byte) i; 
    } 

    public static String encodeString(String s) { 
     return new String(encode(s.getBytes())); 
    } 

    public static char[] encode(byte[] in) { 
     return encode(in, in.length); 
    } 

    public static char[] encode(byte[] in, int iLen) { 
     int oDataLen = (iLen * 4 + 2)/3; 
     int oLen = ((iLen + 2)/3) * 4; 
     char[] out = new char[oLen]; 
     int ip = 0; 
     int op = 0; 
     while (ip < iLen) { 
      int i0 = in[ip++] & 0xff; 
      int i1 = ip < iLen ? in[ip++] & 0xff : 0; 
      int i2 = ip < iLen ? in[ip++] & 0xff : 0; 
      int o0 = i0 >>> 2; 
      int o1 = ((i0 & 3) << 4) | (i1 >>> 4); 
      int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); 
      int o3 = i2 & 0x3F; 
      out[op++] = map1[o0]; 
      out[op++] = map1[o1]; 
      out[op] = op < oDataLen ? map1[o2] : '='; 
      op++; 
      out[op] = op < oDataLen ? map1[o3] : '='; 
      op++; 
     } 
     return out; 
    } 

    public static String decodeString(String s) { 
     return new String(decode(s)); 
    } 

    public static byte[] decode(String s) { 
     return decode(s.toCharArray()); 
    } 

    public static byte[] decode(char[] in) { 
     int iLen = in.length; 
     if (iLen % 4 != 0) throw new IllegalArgumentException("Length of Base64 encoded input string is not a multiple of 4."); 
     while (iLen > 0 && in[iLen - 1] == '=') 
      iLen--; 
     int oLen = (iLen * 3)/4; 
     byte[] out = new byte[oLen]; 
     int ip = 0; 
     int op = 0; 
     while (ip < iLen) { 
      int i0 = in[ip++]; 
      int i1 = in[ip++]; 
      int i2 = ip < iLen ? in[ip++] : 'A'; 
      int i3 = ip < iLen ? in[ip++] : 'A'; 
      if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) throw new IllegalArgumentException("Illegal character in Base64 encoded data."); 
      int b0 = map2[i0]; 
      int b1 = map2[i1]; 
      int b2 = map2[i2]; 
      int b3 = map2[i3]; 
      if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) throw new IllegalArgumentException("Illegal character in Base64 encoded data."); 
      int o0 = (b0 << 2) | (b1 >>> 4); 
      int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2); 
      int o2 = ((b2 & 3) << 6) | b3; 
      out[op++] = (byte) o0; 
      if (op < oLen) out[op++] = (byte) o1; 
      if (op < oLen) out[op++] = (byte) o2; 
     } 
     return out; 
    } 
} 

这是logcat的输出。 82号线是byte[] decryptedInByte = pkCipher.doFinal(encrypted.getBytes());

03-15 01:02:23.855: E/TEST(16749): java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block 
03-15 01:02:23.855: E/TEST(16749): at com.android.org.bouncycastle.jce.provider.JCERSACipher.engineDoFinal(JCERSACipher.java:457) 
03-15 01:02:23.855: E/TEST(16749): at javax.crypto.Cipher.doFinal(Cipher.java:1111) 
03-15 01:02:23.855: E/TEST(16749): at com.example.testing.app.Main.decrypt(Main.java:82) 
03-15 01:02:23.855: E/TEST(16749): at com.example.testing.app.Main.onCreate(Main.java:46) 
03-15 01:02:23.855: E/TEST(16749): at android.app.Activity.performCreate(Activity.java:5163) 
03-15 01:02:23.855: E/TEST(16749): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094) 
03-15 01:02:23.855: E/TEST(16749): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2061) 
03-15 01:02:23.855: E/TEST(16749): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2122) 
03-15 01:02:23.855: E/TEST(16749): at android.app.ActivityThread.access$600(ActivityThread.java:140) 
03-15 01:02:23.855: E/TEST(16749): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1228) 
03-15 01:02:23.855: E/TEST(16749): at android.os.Handler.dispatchMessage(Handler.java:99) 
03-15 01:02:23.855: E/TEST(16749): at android.os.Looper.loop(Looper.java:137) 
03-15 01:02:23.855: E/TEST(16749): at android.app.ActivityThread.main(ActivityThread.java:4895) 
03-15 01:02:23.855: E/TEST(16749): at java.lang.reflect.Method.invokeNative(Native Method) 
03-15 01:02:23.855: E/TEST(16749): at java.lang.reflect.Method.invoke(Method.java:511) 
03-15 01:02:23.855: E/TEST(16749): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994) 
03-15 01:02:23.855: E/TEST(16749): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761) 
03-15 01:02:23.855: E/TEST(16749): at dalvik.system.NativeStart.main(Native Method) 

public_key.pem

-----BEGIN PUBLIC KEY----- 
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0fri4+tn5BAVBGXXpPjn 
rwtHJD2K9JCexyuE1+xPlPIDTvHrY4SefBIKoTdFljLgZPOXVrA+p9Qmv5YnVwa/ 
WAwLCQG8YjbqjJDTRWiV5RN/gidFuFQS7e5P10uy8rY3XUAI8J3poYPTjmSowDmw 
JkBholrybC17zmXlUjlfSry+1ts48ijW6Mq6q3n08uFPtUJGLS8NXApkR0sftPm0 
dI+DlLIOHsFnPBfBwcAUlf/JVBgAm/C6sQXuCjLkFu9wVbmyG3ht8TjO/Q9xeqGQ 
jY8Tu+if7mQd6xXVDP3b1x+CQ4DhQ6iZETEXj0GxOBugISZxBx0KLug0dhBliES7 
TQIDAQAB 
-----END PUBLIC KEY----- 

private_key.pem

-----BEGIN RSA PRIVATE KEY----- 
MIIEpAIBAAKCAQEA0fri4+tn5BAVBGXXpPjnrwtHJD2K9JCexyuE1+xPlPIDTvHr 
Y4SefBIKoTdFljLgZPOXVrA+p9Qmv5YnVwa/WAwLCQG8YjbqjJDTRWiV5RN/gidF 
uFQS7e5P10uy8rY3XUAI8J3poYPTjmSowDmwJkBholrybC17zmXlUjlfSry+1ts4 
8ijW6Mq6q3n08uFPtUJGLS8NXApkR0sftPm0dI+DlLIOHsFnPBfBwcAUlf/JVBgA 
m/C6sQXuCjLkFu9wVbmyG3ht8TjO/Q9xeqGQjY8Tu+if7mQd6xXVDP3b1x+CQ4Dh 
Q6iZETEXj0GxOBugISZxBx0KLug0dhBliES7TQIDAQABAoIBAQCjTraLgJgqPX+7 
DeHrQlIeR20q+FpL3vY9/NCyhe1W7+o2ydvCaHBCGl3+CFiseiEfInw/RY9VQ6Bn 
PMaX3n2OYr9qX9k9oWxFqpVF1BNQOBvhA94rf+fA+KlLzmn8bk8czSKm0InVvgsZ 
IZxE9BjVhxjoBkeobq9tVL5HdqtwGXaaLga95LQDvyYpFqTTTCzcDAB1GaUsdAJq 
tqqojk2+p49zECnWJRcdytaXH+FA8zkIwK/fyejoFW37sZn52aZYJSKs2Yg7pm1E 
GjFE94rtfxdn1oPCD2QBAmyKKQKk2LJJ/JPFoZ98nnOXaSdjklEwgf3OAbA8wAuY 
U23Ny1LBAoGBAO8zZbf85gLEsUve8QYxaq0qXhZX1+ZMbIGVLuhGBpzXf7ldyO5e 
PWR4mwTlhddnVhZNlF++BX+A8tXkVvvBXyS3YcTuzoC/rXP9YuSDYHgp64ic2Qhb 
1iRtBGwHmB6AS5UyxAZMjHqoMki1WLN5eVP+emFQzwuzWv+oyhb9VawVAoGBAOC6 
ILApFi22DJXnR/Ds/nRLLkwYRUVYuB54fGbZrJgTaCLhMpHIYFgh+NAtXqFtrwDT 
NxJDjniVaHpAww69T8O4FOlMEFTF3grWAnMdKRaD/nzK1TtgHLxOOyFBesUiiUZn 
PfJJ/DMm8FywZmFmEU1ge9+Tbje1Hmgj/8TwPkhZAoGAHO6zlACT9avC4jFyJ9Sc 
WZuxS7SOWb3OthHMXa3yqM/sFAjDAAoIFPn9jicQ/E/0erghhT8fvR9kv/hhiQwH 
rRI9UiuscKg+m7P/XTKC3aX8ZkbKfZdWHIvPKB33CWFtQvuj+DsUFtX3VxIQS40a 
3sz+En1KvdiQ3jGVWBiGX00CgYEA21jRTyDLZRKsdiSpM6AfPaOkLOIDuww9qoAv 
7LPKoyVOH71vfpv2bg+6rHecRjSo/EUtG8aU6V3r/Gf5/AkMMh0bTBvSVOxNLoZ1 
Hab40+FCJMxWFP5bDfHOBUfEbWaoVu+upy9P2x3GvrHvPGJDwSLLxg5BJl7CryN0 
IuXb5QECgYAk8/J3p30MVVwXdRYqg79h4itBZS62oL6//dchD58SubWiSTIahsR5 
5v56BzkHC0VLow3eiKE4+tO94G0Gvnw74TgpWOCwEQvneJv5eEHzi9CvmyzJ+hIX 
N1o7nPr6GWav+m1JRCqdU1Dh/wDV5grw0kBQ0fhT/GaMwWkBXWumEQ== 
-----END RSA PRIVATE KEY----- 
+1

当你加密“你好”然后解密产生的加密文本会发生什么?它工作吗? – 2013-03-15 08:22:17

+0

Nvmd,已解决。在下面发布答案。 – Synaero 2013-03-15 08:34:59

回答

1

我曾在解密方法错了电话。 正确的调用如下...

public static String decrypt(InputStream stream, String encrypted) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, 
     NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 

    byte[] encodedKey = new byte[stream.available()]; 
    stream.read(encodedKey); 
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    PublicKey pkPublic = kf.generatePublic(publicKeySpec); 

    Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 
    pkCipher.init(Cipher.DECRYPT_MODE, pkPublic); 

    byte[] decoded = Base64Coder.decode(encrypted); 
    byte[] decryptedInByte = pkCipher.doFinal(decoded); 
    return new String(decryptedInByte); 
}