我在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:提供者不可用:SunJCE
我从行中删除了指定的提供程序"SunJCE"。
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
我在这里找到了这个问题的解决方案
现在我在服务器端得到这个错误:
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,但我仍然有相同的错误
尝试以下代码:调用加密方法如下: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");
}
这取决于安全提供程序。Android和JVM中的默认值不同,并非所有的Sun/Oracle算法都存在于Android上。
我遇到了几乎相同的问题,并通过切换到弹跳城堡(BC)来解决它。它存在于双方,并以完全相同的方式工作。
我使用"RSA/ECB/PKCS1Padding"作为两侧的转换。它起作用了。
您的代码不会在除Oracle之外的任何Java虚拟机上运行。原因是您请求了一个名为"SunJCE"的特定加密提供程序,它是Oracle(以前的Sun)的JCE API的参考实现。
只需更改代码即可接受任何能够处理请求算法的提供商:
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
Yo Brother,我刚刚在安卓系统上制作了一个使用加密的应用程序
看看下面这个问题
基于Java 256位AES密码的加密
看看吴(14分)的回复
只需省略import org.apache.commons.codec.binary.Hex的使用;以及它的方法(由于Hex类中使用的方法来自新版本的apacheapi,并且android已经在旧版本的apache中构建,另外,在android中,原生api优先于外部库/api)
从这个链接下载并参考org.apache.commonhttp://commons.apache.org/proper/commons-codec/
我希望它能帮助