我在java中做了一个简单的加密/解密字符串类并对其进行了测试。它工作正常,现在我试图在Android设备中使用它来加密字符串,将其发送到我的服务器并在那里解密它。全部使用相同的自定义类。为什么这不起作用?它根本不受支持吗?为此目的,我还能做些什么来轻松加密/解密字符串?不接受Base64:)
package crypto;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Crypto {
public static byte[] encrypt(String message) throws Exception
{
String symmetricKey = "25Ae1f1711%z1 )1";
SecretKeySpec aesKey = new SecretKeySpec(symmetricKey.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(message.getBytes());
}
public static String decrypt(byte[] encryptedMessage) throws Exception
{
String symmetricKey = "25Ae1f1711%z1 )1";
SecretKeySpec aesKey = new SecretKeySpec(symmetricKey.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(encryptedMessage));
}
}
在logcat中我可以看到弹出以下异常:java.security.NoSuchProviderException:Provider not avalible:SunJCE
我从该行删除了指定的提供程序“SunJCE”。
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
我在here
上找到了解决方法现在我在服务器端遇到此错误:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:317)
at javax.crypto.Cipher.doFinal(Cipher.java:1813)
at crypto.Crypto.decrypt(Crypto.java:20)
at io.network.UDPServer.run(UDPServer.java:37
尝试使用BC,但我仍然有同样的错误
答案 0 :(得分:4)
试试这段代码:
调用加密方法如下:encrypt_text = Encrypt(Text,"avs3qt");
Encrypt
函数定义:
String Encrypt(String text, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if (len > keyBytes.length)
len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
BASE64Decoder encoder = new BASE64Decoder();
return encoder.encodeBytes(results);
}
调用Decrypt
这样的方法:
decrypt_text = Decrypt(Text, "avs3qt");
功能定义:
String Decrypt(String text, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if (len > keyBytes.length)
len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec,ivSpec);
BASE64Decoder decoder = new BASE64Decoder();
byte[] results = cipher.doFinal(decoder.decode(text));
return new String(results, "UTF-8");
}
答案 1 :(得分:2)
这取决于安全提供商。在Android和JVM中有不同的默认值,并且Android上也不存在所有Sun / Oracle算法。
我有几乎相同的问题,并通过切换到弹跳城堡(BC)解决它。它存在于两侧,并且在完全相同的情况下工作。
我正在使用“RSA / ECB / PKCS1Padding”作为双方的转换。它的工作。
答案 2 :(得分:2)
除了Oracle之外,您的代码不会在任何 Java VM上运行。原因是您请求一个名为“SunJCE”的特定加密提供程序,它是Oracle(以前称为Sun)的JCE API的参考实现。
只需更改代码即可接受任何能够处理所请求算法的提供程序:
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
答案 3 :(得分:1)
看看以下问题
Java 256-bit AES Password-Based Encryption
查看wufoo(有14分的人)给出的回复
只需省略使用import org.apache.commons.codec.binary.Hex;和它的方法(由于Hex类中使用的方法来自apache api和android的新版本已经内置了旧版本的apache,在Android原生api中加上优先于外部库/ api)
并从此链接http://commons.apache.org/proper/commons-codec/
下载并引用org.apache.common我希望它有所帮助