在 Android 中使用 RSA 解密 AES 密钥
Decrypt AES Key with RSA in Android
我正在尝试使用 AES(128 位)加密一个小文件,然后使用 RSA(1024 位)加密 AES 密钥。这很好用。
作为合乎逻辑的下一步,我尝试使用 RSA 解密 AES 密钥。
用 RSA 解密 returns 一个 128 字节的块,但我的 AES 密钥只有 16 字节长。
经过研究,我读到我需要将 RSA 与 Padding 一起使用,所以我使用了 RSA/ECB/PKCS1Padding.
但这总是给我以下异常 -
javax.crypto.BadPaddingException: error:04000089:RSA routines:OPENSSL_internal:PKCS_DECODING_ERROR
at com.android.org.conscrypt.NativeCrypto.RSA_private_decrypt(Native Method)
at com.android.org.conscrypt.OpenSSLCipherRSA$DirectRSA.doCryptoOperation(OpenSSLCipherRSA.java:402)
at com.android.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:314)
at javax.crypto.Cipher.doFinal(Cipher.java:2055)
我的密钥对生成逻辑 -
KeyPairGenerator keyGen = null;
try {
keyGen = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
keyGen.initialize(1024);
byte[] publicKey = keyGen.genKeyPair().getPublic().getEncoded();
byte[] privateKey = keyGen.genKeyPair().getPrivate().getEncoded();
Util.save("privateKey", rsa.encryptBASE64(privateKey), this);
Util.save("publicKey", rsa.encryptBASE64(publicKey), this);
我的加密逻辑 -
public static byte[] encryptByPublicKey(byte[] data, String key)
throws Exception {
byte[] keyBytes = decryptBASE64(key);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
我的解密逻辑 -
public static byte[] decryptByPrivateKey(byte[] data, String key)
throws Exception {
byte[] keyBytes = decryptBASE64(key);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
任何帮助将不胜感激。
谁能指导我如何将解密的 RSA 块转换为 AES 密钥?
测试这就是我在我的代码中所做的。加密和解密是背靠背的步骤-
String aesKeyCipherBase64 = rsa.encryptBASE64(rsa.encryptByPublicKey(secretKey.getEncoded(), myPublicKeyString));
byte[] aesKeyRecovered = rsa.decryptByPrivateKey(rsa.decryptBASE64(aesKeyCipherBase64),myPrivateKeyString);
Base64 实用方法 -
public static byte[] decryptBASE64(String key) {
return Base64.decode(key, Base64.NO_PADDING|Base64.NO_WRAP|Base64.NO_PADDING|Base64.URL_SAFE);
}
public static String encryptBASE64(byte[] key) {
return Base64.encodeToString(key, Base64.NO_PADDING|Base64.NO_WRAP|Base64.NO_PADDING|Base64.URL_SAFE);
}
public static void save(String key, String value, Activity activity) {
SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(key, value);
editor.commit();
}
String myPublicKeyString = Util.getPublicKey(this);
String myPrivateKeyString = Util.getPrivateKey(this);
public static String getPrivateKey(Activity activity) {
SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
return sharedPref.getString("privateKey", null);
}
public static String getPublicKey(Activity activity) {
SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
return sharedPref.getString("publicKey", null);
}
我更改了以下内容 -
byte[] publicKey = keyGen.genKeyPair().getPublic().getEncoded();
byte[] privateKey = keyGen.genKeyPair().getPrivate().getEncoded();
至 -
KeyPair kp = keyGen.genKeyPair();
byte[] publicKey = kp.getPublic().getEncoded();
byte[] privateKey = kp.getPrivate().getEncoded();
我分别生成了一个新的密钥对来访问 public 和私钥。
感谢@president-james-moveon-polk 为我指明了正确的方向。
我正在尝试使用 AES(128 位)加密一个小文件,然后使用 RSA(1024 位)加密 AES 密钥。这很好用。
作为合乎逻辑的下一步,我尝试使用 RSA 解密 AES 密钥。
用 RSA 解密 returns 一个 128 字节的块,但我的 AES 密钥只有 16 字节长。 经过研究,我读到我需要将 RSA 与 Padding 一起使用,所以我使用了 RSA/ECB/PKCS1Padding.
但这总是给我以下异常 -
javax.crypto.BadPaddingException: error:04000089:RSA routines:OPENSSL_internal:PKCS_DECODING_ERROR
at com.android.org.conscrypt.NativeCrypto.RSA_private_decrypt(Native Method)
at com.android.org.conscrypt.OpenSSLCipherRSA$DirectRSA.doCryptoOperation(OpenSSLCipherRSA.java:402)
at com.android.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:314)
at javax.crypto.Cipher.doFinal(Cipher.java:2055)
我的密钥对生成逻辑 -
KeyPairGenerator keyGen = null;
try {
keyGen = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
keyGen.initialize(1024);
byte[] publicKey = keyGen.genKeyPair().getPublic().getEncoded();
byte[] privateKey = keyGen.genKeyPair().getPrivate().getEncoded();
Util.save("privateKey", rsa.encryptBASE64(privateKey), this);
Util.save("publicKey", rsa.encryptBASE64(publicKey), this);
我的加密逻辑 -
public static byte[] encryptByPublicKey(byte[] data, String key)
throws Exception {
byte[] keyBytes = decryptBASE64(key);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
我的解密逻辑 -
public static byte[] decryptByPrivateKey(byte[] data, String key)
throws Exception {
byte[] keyBytes = decryptBASE64(key);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
任何帮助将不胜感激。
谁能指导我如何将解密的 RSA 块转换为 AES 密钥?
测试这就是我在我的代码中所做的。加密和解密是背靠背的步骤-
String aesKeyCipherBase64 = rsa.encryptBASE64(rsa.encryptByPublicKey(secretKey.getEncoded(), myPublicKeyString));
byte[] aesKeyRecovered = rsa.decryptByPrivateKey(rsa.decryptBASE64(aesKeyCipherBase64),myPrivateKeyString);
Base64 实用方法 -
public static byte[] decryptBASE64(String key) {
return Base64.decode(key, Base64.NO_PADDING|Base64.NO_WRAP|Base64.NO_PADDING|Base64.URL_SAFE);
}
public static String encryptBASE64(byte[] key) {
return Base64.encodeToString(key, Base64.NO_PADDING|Base64.NO_WRAP|Base64.NO_PADDING|Base64.URL_SAFE);
}
public static void save(String key, String value, Activity activity) {
SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(key, value);
editor.commit();
}
String myPublicKeyString = Util.getPublicKey(this);
String myPrivateKeyString = Util.getPrivateKey(this);
public static String getPrivateKey(Activity activity) {
SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
return sharedPref.getString("privateKey", null);
}
public static String getPublicKey(Activity activity) {
SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
return sharedPref.getString("publicKey", null);
}
我更改了以下内容 -
byte[] publicKey = keyGen.genKeyPair().getPublic().getEncoded();
byte[] privateKey = keyGen.genKeyPair().getPrivate().getEncoded();
至 -
KeyPair kp = keyGen.genKeyPair();
byte[] publicKey = kp.getPublic().getEncoded();
byte[] privateKey = kp.getPrivate().getEncoded();
我分别生成了一个新的密钥对来访问 public 和私钥。
感谢@president-james-moveon-polk 为我指明了正确的方向。