我正在使用Bouncy Castle加密。我使用RSA,公钥存储在PEM文件中。我发现当我在简单的控制台项目(而不是Android项目)中运行代码时,一切正常 - 这意味着加密的字符串可以使用私钥解密。但是,当我在Android应用程序中运行相同的代码时,加密的字节数组对于相同的公钥是不同的,并且不会被识别为给定密钥对的有效加密。
详情: 这是使用Bouncy Castle加密字符串并从控制台项目中取出的代码。这个工作正常,并产生加密的字符串,这是密钥对的有效加密,可以解密。
private static void encrypt() {
try {
//This example uses the Bouncy Castle library
Security.addProvider(new BouncyCastleProvider());
String plainText = "This needs to be encrypted";
String public_key_file = "PublicKey.pem";
//Load public key
PEMParser parser = new PEMParser(new FileReader(public_key_file));
Object key = parser.readObject();
parser.close();
PublicKey pubKey = null;
if (key instanceof SubjectPublicKeyInfo) {
SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) key;
pubKey = KeyFactory.getInstance("RSA").generatePublic
(new X509EncodedKeySpec(spki.getEncoded()));
}
//Encrypt the plain text
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted_data = cipher.doFinal(plainText.getBytes());
String encoded_data = new String(Base64.encode(encrypted_data));
System.out.println("Encrypted Value:");
System.out.println(encoded_data);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
现在这里是从Android应用程序中取出的代码。唯一重要的区别是从Assets文件夹中读取密钥文件。此代码也会生成加密字符串,但它对密钥对无效,无法解密。
public void encrypt(Context context) {
try {
//This example uses the Bouncy Castle library
Security.addProvider(new BouncyCastleProvider());
String plainText = "This needs to be encrypted";
String public_key_file = "PublicKey.pem";
//Load public key
InputStream inputStream = context.getAssets().open(public_key_file);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
// read from the input stream reader
PEMParser parser = new PEMParser(inputStreamReader);
Object key = parser.readObject();
parser.close();
PublicKey pubKey = null;
if (key instanceof SubjectPublicKeyInfo) {
SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) key;
pubKey = KeyFactory.getInstance("RSA").generatePublic
(new X509EncodedKeySpec(spki.getEncoded()));
}
//Encrypt the plain text
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted_data = cipher.doFinal(plainText.getBytes());
String encoded_data =
new String(Base64.encode(encrypted_data));
Log.d("MyApp", "Encrypted Value:");
Log.d("MyApp", encoded_data);
} catch (Exception ex) {
Log.d("MyApp", ex.getMessage());
}
}
在这两种情况下,事情都是一样的:
与众不同:环境。一个是控制台程序,另一个是Android App。
调试时进一步调查 我观察到,当运行控制台程序时,KeyFactory返回" sun.security.rsa.RSAPublicKeyImpl"的实例。但是,当运行Android应用程序时,KeyFactory返回" com.android.org.conscrypt.OpenSSLRSAPublicKey"的实例。不确定这是不是问题所在。对于相同的纯文本和公钥,加密的字节数组是不同的。
非常感谢任何帮助。
先谢谢, 和Sandeep