Java Android/JVM在RSA解密中的差异
我正在尝试解密一个字符串,我在别处加密了这个字符串。这是我的密码:Java Android/JVM在RSA解密中的差异,java,android,rsa,Java,Android,Rsa,我正在尝试解密一个字符串,我在别处加密了这个字符串。这是我的密码: private void test() { try { String stringMessage="Sf3O7Lr2+WN5szGyLejL3CjuBRZtQ72+ZBmgVTgWnatQZxUElzaBqFa1p0SVBqe9VWVxCxdEkejMVtDGEr0UJSVSK8EB/fPI6v8JE8dIu0JN0mMs4xlowhITy0tQR+1pcBtDFjzOl33xxQcq5JuPezxRD
private void test() {
try {
String stringMessage="Sf3O7Lr2+WN5szGyLejL3CjuBRZtQ72+ZBmgVTgWnatQZxUElzaBqFa1p0SVBqe9VWVxCxdEkejMVtDGEr0UJSVSK8EB/fPI6v8JE8dIu0JN0mMs4xlowhITy0tQR+1pcBtDFjzOl33xxQcq5JuPezxRDxFIp+IVkD8FdpqlttEKf2Tvqw9tqsdgiBKb5xDvKrkIDQXdLBh1gbAVZDSJYGHRkcOA8vz2ty/PeooKkfDK6IOn7KBwOBgSRgQr/MLBF3Xk2vRWgVGRh/fRkzu21EWo99Q5moWKxWl3HW/bbgTBQTb097XP3NTID9kSPhCfL0BEfBxonuNse5GBoeRnCw==";
//Convert String back to Byte[] and decrpt
byte[] byteMessage = Base64.decodeBase64(stringMessage.getBytes("UTF-8"));
System.out.println("ENCRYPTED MESSAGE byte Length: "+byteMessage.length);
String decryptedMsg = decryptString(byteMessage, loadCASPrivateKey());
System.out.println(decryptedMsg);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private static String decryptString(byte[] message, Key privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherData = cipher.doFinal(message);
return new String(cipherData, "UTF-8");
}
private PrivateKey loadCASPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
InputStream is = getClass().getResourceAsStream( "/keys/app-private.key" );
if (is == null) {
System.out.println("NULL");
}
byte[] encodedPrivateKey = new byte[(int) 2000];
is.read(encodedPrivateKey);
is.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return privateKey;
}
这在我的桌面JVM下100%起作用,但是当我在Android emulator中运行它时,我得到:
04-24 22:42:21.011:I/系统输出(1041):
��K���_��*�ݣ���93|@0�̍4�y)��Q�K�;*A.����E�<代码>#��A.�
�oiu:�����W5@$�W�J��代码>美国�R�Ocxٰ&����L
�w'/�D�8uA��ؔ�{�4$�U�0��{Ԑ��t!9��N��
��A.��'Jdt2�T�T�D��k+k�;������ ����女朋友��\�rڼ��>]�y+^w� 由于您正在读取一个2000字节的数组,并且您的密钥可能是128位(1024位)或256位(2048位),因此您可能会将
KeyFactory
垃圾送入字节长。此外,您不应该直接使用RSA进行加密:这存在安全问题。您可以加密的数据大小受RSA密钥大小的限制。多亏了GregS在评论中的帮助。这是一个适合我的解决方案
private void test() {
try {
String stringMessage="GEQRpAPA577ks/QveudNkk7H9DjItKGLDYW6xhH1YJGabCVzrkejkBh6S+APwEXxB84UV/q0sO5rqkgXWONJQ8CoMTfqXtUkAAwkYHSc86eGewkM8WpctA0AyNVFonOxDCXm84Uq8JRMzqskSH5VXHmMxvHIvpFgdhmt9Ir0cKWzoLsuvgfY9hfypfEyBXGZcoptQeKhsZxRGIlxbXhrFl/LqhC+F6vYtZ/j5pv2LUP38wh2rTCKnAQ+xvC+7wn5SVzt/Wbr/q7GjCoJuU9uFHQSS49KQDt+BzJL2XNwAMmdbC+XHYkEBBWxVSS+0hdSQxoaKVZZJk4hTnHwQlBAkw==";
//Convert String back to Byte[] and decrpt
byte[] byteMessage = Base64.decodeBase64(stringMessage.getBytes("UTF-8"));
System.out.println("ENCRYPTED MESSAGE byte Length: "+byteMessage.length);
String decryptedMsg = decryptString(byteMessage, loadCASPrivateKey());
System.out.println(decryptedMsg);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private static String decryptString(byte[] message, Key privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, NoSuchProviderException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("RSA/None/NoPadding","BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherData = cipher.doFinal(message);
return new String(cipherData, "UTF-8");
}
private PrivateKey loadCASPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
InputStream is = getClass().getResourceAsStream( "/keys/app-private.key" );
if (is == null) {
System.out.println("NULL");
}
byte[] encodedPrivateKey = new byte[(int) 1216];
is.read(encodedPrivateKey);
is.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return privateKey;
}
你会建议我用什么替换字节数组?JVM和Android之间它输入KeyFactory的方式会不同吗?我正在使用RSA加密固定长度的随机散列。谢谢。读取流并只使用文件/资产中的字节数。不确定你想做什么,但加密散列通常被称为“签名”并使用私钥完成,并使用公钥验证。您在桌面上使用的JCE提供程序和Java版本是什么?请列出所有不使用默认值的算法,尝试查找支持哪些RSA密码。它们在不同的平台上可能不同。
Cipher.getInstance()
接受一个由算法/模式/填充组成的字符串参数。您只提供了算法,并获得了其他两个的默认值。此外,您需要显示encryptString
方法,以便我们可以将其与decryptString
方法进行比较。@GregS-谢谢。我已经添加了encryptString部分。我将研究密码r、 getInstance,我没有意识到它包含了更多的部分。@GregS-我已经查看并尝试了“RSA/NONE/NoPadding”。但是我得到了一个NoSuchAlgorithmException。修复了它。感谢指针。添加了一个安全提供程序,然后正确地声明了算法/模式/填充。:)
private void test() {
try {
String stringMessage="GEQRpAPA577ks/QveudNkk7H9DjItKGLDYW6xhH1YJGabCVzrkejkBh6S+APwEXxB84UV/q0sO5rqkgXWONJQ8CoMTfqXtUkAAwkYHSc86eGewkM8WpctA0AyNVFonOxDCXm84Uq8JRMzqskSH5VXHmMxvHIvpFgdhmt9Ir0cKWzoLsuvgfY9hfypfEyBXGZcoptQeKhsZxRGIlxbXhrFl/LqhC+F6vYtZ/j5pv2LUP38wh2rTCKnAQ+xvC+7wn5SVzt/Wbr/q7GjCoJuU9uFHQSS49KQDt+BzJL2XNwAMmdbC+XHYkEBBWxVSS+0hdSQxoaKVZZJk4hTnHwQlBAkw==";
//Convert String back to Byte[] and decrpt
byte[] byteMessage = Base64.decodeBase64(stringMessage.getBytes("UTF-8"));
System.out.println("ENCRYPTED MESSAGE byte Length: "+byteMessage.length);
String decryptedMsg = decryptString(byteMessage, loadCASPrivateKey());
System.out.println(decryptedMsg);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private static String decryptString(byte[] message, Key privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, NoSuchProviderException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("RSA/None/NoPadding","BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherData = cipher.doFinal(message);
return new String(cipherData, "UTF-8");
}
private PrivateKey loadCASPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
InputStream is = getClass().getResourceAsStream( "/keys/app-private.key" );
if (is == null) {
System.out.println("NULL");
}
byte[] encodedPrivateKey = new byte[(int) 1216];
is.read(encodedPrivateKey);
is.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return privateKey;
}