Java 使用 AES-RSA 的加密在 Eclipse 中有效,但在 Android Studio 中无效
Java Encryption with AES-RSA works in Eclipse but not in Android Studio
这可能是发生在我身上的最奇怪的事情了。 代码在 Eclipse 中运行完美,但是如果我尝试在 Android Studio 中使用它,它会失败。
2 天后,我认为它可能与 Commons-Codec 库有关,但在这一点上,在互联网上到处搜索之后,我找不到解决我的问题的方法。我昨晚真的没睡,试图找到解决办法。
这是我的代码,我只粘贴了我认为相关的内容,但如果您需要完整的代码,请告诉我。
这是在服务器端,运行 在 Ubuntu 服务器上。
private String cifrarClaveAES(String clavepub) throws Exception{
byte[] sigBytes2 = new Base64().decode(clavepub);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes2);
KeyFactory keyFact = KeyFactory.getInstance("RSA");
PublicKey pubKey2 = keyFact.generatePublic(x509KeySpec);
try {
Cipher rsa;
rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, pubKey2);
byte[] array = rsa.doFinal(miclaveAES.getBytes("UTF-8"));
String prueba = new String(new Base64().encode(array), "UTF-8");
return prueba;
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
private String desencriptar(String criptograma, SecretKey clave){
try{
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, clave);
byte[] decVal = new Base64().decode(criptograma.getBytes("UTF-8"));
byte[] mensaje = c.doFinal(decVal);
return new String(mensaje, "UTF-8");
}catch (Exception e){
System.out.println("Error al desencriptar");
return null;
}
}
这是运行客户端(AndroidAPP)
private String clavePublicaToString(){ //PublicKeyToString
PublicKey miclaveRSA = claveRSA.getPublic();
byte[] array = miclaveRSA.getEncoded();
String clavePublica = "";
try {
clavePublica = new String(new Base64().encode(array), "UTF-8");
System.out.println(clavePublica);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
return clavePublica;
}
public String descifrarclaveAEScifrada(String mstring) {
byte[] buffer = new byte[0];
try {
buffer = mstring.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
Cipher rsa;
rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.DECRYPT_MODE, claveRSA.getPrivate());
byte[] utf8;
byte[] depaso = new Base64().decode(buffer);
utf8 = rsa.doFinal(depaso);
return new String(utf8, "UTF-8");
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
public String encriptarAES(String mensaje, SecretKey clave){
Cipher c = null;
byte[] criptograma = null;
try {
c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, clave);
byte[] encVal = c.doFinal(mensaje.getBytes("UTF-8"));
criptograma = new Base64().encode(encVal);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new String(criptograma, Charset.defaultCharset());
}
这里是 Android Studio 中的输出。
输出将一些可读字符变为不可读字符,长度永远不会相同。
https://gyazo.com/574be22d0ef8f8b56f7fac805e09be33
输出应该是:ThisIsMyAESkey
您的问题是因为您在指定所使用的算法时不够准确。
当以字符串形式提供密码名称时,例如"RSA" 您应该始终尽可能具体。这意味着包括块模式和填充模式。
我不知道您希望使用哪种填充模式,但请具体说明。尝试使用 RSA/ECB/PKCS1Padding
和 AES/ECB/PKCS5Padding
.
这将使您的代码正常工作,但它远非真正安全。您的密文未经过身份验证,因此可以修改,您当前使用的是 ECB 模式(例如,无 IV),并且您的应用程序没有前向保密性。要使您的代码安全,您还有很长的路要走。
这可能是发生在我身上的最奇怪的事情了。 代码在 Eclipse 中运行完美,但是如果我尝试在 Android Studio 中使用它,它会失败。 2 天后,我认为它可能与 Commons-Codec 库有关,但在这一点上,在互联网上到处搜索之后,我找不到解决我的问题的方法。我昨晚真的没睡,试图找到解决办法。
这是我的代码,我只粘贴了我认为相关的内容,但如果您需要完整的代码,请告诉我。
这是在服务器端,运行 在 Ubuntu 服务器上。
private String cifrarClaveAES(String clavepub) throws Exception{
byte[] sigBytes2 = new Base64().decode(clavepub);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes2);
KeyFactory keyFact = KeyFactory.getInstance("RSA");
PublicKey pubKey2 = keyFact.generatePublic(x509KeySpec);
try {
Cipher rsa;
rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, pubKey2);
byte[] array = rsa.doFinal(miclaveAES.getBytes("UTF-8"));
String prueba = new String(new Base64().encode(array), "UTF-8");
return prueba;
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
private String desencriptar(String criptograma, SecretKey clave){
try{
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, clave);
byte[] decVal = new Base64().decode(criptograma.getBytes("UTF-8"));
byte[] mensaje = c.doFinal(decVal);
return new String(mensaje, "UTF-8");
}catch (Exception e){
System.out.println("Error al desencriptar");
return null;
}
}
这是运行客户端(AndroidAPP)
private String clavePublicaToString(){ //PublicKeyToString
PublicKey miclaveRSA = claveRSA.getPublic();
byte[] array = miclaveRSA.getEncoded();
String clavePublica = "";
try {
clavePublica = new String(new Base64().encode(array), "UTF-8");
System.out.println(clavePublica);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
return clavePublica;
}
public String descifrarclaveAEScifrada(String mstring) {
byte[] buffer = new byte[0];
try {
buffer = mstring.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
Cipher rsa;
rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.DECRYPT_MODE, claveRSA.getPrivate());
byte[] utf8;
byte[] depaso = new Base64().decode(buffer);
utf8 = rsa.doFinal(depaso);
return new String(utf8, "UTF-8");
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
public String encriptarAES(String mensaje, SecretKey clave){
Cipher c = null;
byte[] criptograma = null;
try {
c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, clave);
byte[] encVal = c.doFinal(mensaje.getBytes("UTF-8"));
criptograma = new Base64().encode(encVal);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new String(criptograma, Charset.defaultCharset());
}
这里是 Android Studio 中的输出。 输出将一些可读字符变为不可读字符,长度永远不会相同。
https://gyazo.com/574be22d0ef8f8b56f7fac805e09be33
输出应该是:ThisIsMyAESkey
您的问题是因为您在指定所使用的算法时不够准确。
当以字符串形式提供密码名称时,例如"RSA" 您应该始终尽可能具体。这意味着包括块模式和填充模式。
我不知道您希望使用哪种填充模式,但请具体说明。尝试使用 RSA/ECB/PKCS1Padding
和 AES/ECB/PKCS5Padding
.
这将使您的代码正常工作,但它远非真正安全。您的密文未经过身份验证,因此可以修改,您当前使用的是 ECB 模式(例如,无 IV),并且您的应用程序没有前向保密性。要使您的代码安全,您还有很长的路要走。