我想用 RSA 加密来加密一个字符串。我的公钥/私钥已生成并存储在数据库中。在安卓中,我使用这段代码:
public static String encryptRSAToString(String text, String strPublicKey) {
byte[] cipherText = null;
String strEncryInfoData="";
try {
KeyFactory keyFac = KeyFactory.getInstance("RSA");
KeySpec keySpec = new X509EncodedKeySpec(Base64.decode(strPublicKey.trim().getBytes(), Base64.DEFAULT));
Key publicKey = keyFac.generatePublic(keySpec);
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance("RSA");
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipherText = cipher.doFinal(text.getBytes());
strEncryInfoData = new String(Base64.encode(cipherText,Base64.DEFAULT));
} catch (Exception e) {
e.printStackTrace();
}
return strEncryInfoData.replaceAll("(\\r|\\n)", "");
}
出于调试目的,我尝试使用相同的参数调用此方法 2 次,字符串结果相似(如预期)。
我想在 java 中生成相同的加密字符串。但是,“android.util.Base64”类在 Java 中不可用,因此我尝试使用默认的 Base64 类:
public static String encryptRSAToString(String text, String strPublicKey) {
byte[] cipherText = null;
String strEncryInfoData="";
try {
KeyFactory keyFac = KeyFactory.getInstance("RSA");
KeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(strPublicKey.trim().getBytes()));
Key publicKey = keyFac.generatePublic(keySpec);
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance("RSA");
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipherText = cipher.doFinal(text.getBytes());
strEncryInfoData = new String(Base64.encodeBase64(cipherText));
} catch (Exception e) {
e.printStackTrace();
}
return strEncryInfoData.replaceAll("(\\r|\\n)", "");
}
但是Android中生成的String和java中生成的是不一样的。
在Android端生成:
Ky2T4j1JdI081ZESVJgxZXEf/xmtpehfv/EwpVvKQxUu1JI8lwXP2Rc66jHZRc0P846ZYuF3C9YEmWoKbXGXk2MBuT5KVxa2yoTbwZlMmhVOX3X3Efq0VyaO5zZ4qavIq036cA3MzvQbUAb678UdbALW/CjRCsOdeH+hSCzNQ+0=
在JAVA端生成:
XhSLxfiJUUdZW5kWh0MEPSrqoROBBhNC/krfTx+sdnXML3WegYbMzSvNnPgB8+8Z9joEUBMmoeBI1OhTF6qPFL1EEixkFYAkGaryEFxvN/aFI75kEUj71OHNzAHAuvS+h+9Nssx9psSZ5gc2OoLQH0QtbGDyXB4p+qUGFCde4tY=
有人知道如何解决我的问题吗?
谢谢
最佳答案
看起来你已经因为依赖默认设置而失败了。如果您希望互操作性,切勿这样做。
这是我发现的错误依赖代码中默认值的两个示例。
final Cipher cipher = Cipher.getInstance("RSA");
转换字符串应该是“algorithm/mode/padding”的形式,但您没有使用mode 和padding 规范。结果,您获得了这些的默认值。默认值在 Android 和 Oracle Java 上明显不同。你应该总是fully specify the transformation ,例如:
final Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
另一个不好的例子是
cipherText = cipher.doFinal(text.getBytes());
在 text.getBytes()
中,您依赖于使用平台默认字符集的无参数 getBytes() 方法。但是这个默认的字符集在不同的平台上是不同的,因此这是不可移植的。在我遇到的几乎所有情况下,您都应该指定 UTF-8 字符集。所以正确的行应该是
cipherText = cipher.doFinal(text.getBytes("UTF-8"));
用于在解密方法中重新创建原始字符串的正确字符串构造函数是 String(byte [] data, String charsetName)
.
关于java - Android 和 Java 中的 RSA 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30886589/