无法在Android上解密AES?
我是android开发的新手,现在我在android上实现了一个AES,它可以用用户输入密码加密字符串。加密似乎很好,可以省略Base64/Hex编码的字符串 但当我试图解密它时,问题来了:解密时,遗漏总是让我看到一堆乱七八糟的字符 为了摆脱它,我试着在从字符串转换到字节[]时定义一个字符集(如UTF-8)来调试它,但没有命中,还试着用基64或十六进制编码省略,但都失败了 我还尝试在使用cipher.getInstance方法时定义AES/CBC/PKCS5Padding或仅定义AES,但仍然没有成功 真烦人,你们能帮帮我吗 忘了提到我曾经问过一个类似的问题,那里的语法问题已经纠正了 下面是代码: 用于加密无法在Android上解密AES?,android,base64,hex,aes,Android,Base64,Hex,Aes,我是android开发的新手,现在我在android上实现了一个AES,它可以用用户输入密码加密字符串。加密似乎很好,可以省略Base64/Hex编码的字符串 但当我试图解密它时,问题来了:解密时,遗漏总是让我看到一堆乱七八糟的字符 为了摆脱它,我试着在从字符串转换到字节[]时定义一个字符集(如UTF-8)来调试它,但没有命中,还试着用基64或十六进制编码省略,但都失败了 我还尝试在使用cipher.getInstance方法时定义AES/CBC/PKCS5Padding或仅定义AES,但仍然没
public String AESEncrypt(String sKey, String PlainMsg)
throws Exception {
//Try use some Android based alert dialog to catch this exception.
if (sKey == null) {
Log.e("SecureChat", "IllegalArgumentException Catched");
throw new IllegalArgumentException ("NULL Secret NOT ALLOWED!");
}
/*Old Method
//byte[] rawKey = getRawKey(sKey.getBytes("UTF-8"));
byte[] rawKey = getRawKey(sKey.getBytes());
//Encrypt start
SecretKeySpec keySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
//byte[] cipherText = cipher.doFinal(PlainMsg.getBytes("UTF-8"));
byte[] cipherText = cipher.doFinal(PlainMsg.getBytes());
return Base64Encoded(cipherText);
*/
//New Method
byte[] salt = getSalt();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
KeySpec spec = new PBEKeySpec(sKey.toCharArray(), salt, 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
//Encryption Process
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] cipherText = cipher.doFinal(PlainMsg.getBytes());
//return Base64Encoded(cipherText);
//Hex
return toHex(cipherText);
}
用于解密
public String AESDecrypt(String sKey, String EncryptMsg)
throws Exception {
/*Old Method
//byte[] rawKey = getRawKey(sKey.getBytes("UTF-8"));
byte[] rawKey = getRawKey(sKey.getBytes());
SecretKeySpec keySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
//byte[] plainText = Base64Decoded(EncryptMsg.getBytes("UTF-8"));
byte[] plainText = Base64Decoded(EncryptMsg);
cipher.doFinal(plainText);
return new String(plainText, "UTF-8");
*/
//New Method
byte[] salt = getSalt();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
KeySpec spec = new PBEKeySpec(sKey.toCharArray(), salt, 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
//byte[] bCipherText = Base64Decoded(EncryptMsg);
//Hex
byte[] bCipherText = toByte(EncryptMsg);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
cipher.doFinal(bCipherText);
return new String(bCipherText);
}
private byte[] getSalt() throws NoSuchAlgorithmException {
/*Mark for old key method
//Initialize the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
//Init for 256bit AES key
kgen.init(Constants.AES_KEY_SIZE, sr);;
SecretKey secret = kgen.generateKey();
//Get secret raw key
byte[] rawKey = secret.getEncoded();
return rawKey;
*/
//New key method with some salt
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte[] ransalt = new byte[20];
random.nextBytes(ransalt);
return ransalt;
}
@Override
public byte[] getRawKey(byte[] seed) throws Exception {
/*Old Method
//Initialize the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
//Init for 256bit AES key
kgen.init(Constants.AES_KEY_SIZE, sr);
SecretKey secret = kgen.generateKey();
//Get secret raw key
byte[] rawKey = secret.getEncoded();
return rawKey;
*/
return null;
}
/**
*
* @param toBeDecoded
* @return
*/
public byte[] Base64Decoded(String toBeDecoded) {
byte[] decoded = Base64.decode(toBeDecoded, 0);
return decoded;
}
//Hex Mode
public String toHex(String txt) {
return toHex(txt.getBytes());
}
public String fromHex(String hex) {
return new String(toByte(hex));
}
public byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
public String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final String HEX = "0123456789ABCDEF";
private void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
publicstringaesdefcrypt(stringskey,stringencryptmsg)
抛出异常{
/*旧方法
//byte[]rawKey=getRawKey(sKey.getBytes(“UTF-8”);
byte[]rawKey=getRawKey(sKey.getBytes());
SecretKeySpec keySpec=新的SecretKeySpec(rawKey,“AES”);
Cipher Cipher=Cipher.getInstance(“AES”);
cipher.init(cipher.DECRYPT_模式,keySpec);
//字节[]明文=base64解码(EncryptMsg.getBytes(“UTF-8”);
字节[]明文=base64已解码(EncryptMsg);
cipher.doFinal(纯文本);
返回新字符串(纯文本,“UTF-8”);
*/
//新方法
字节[]salt=getSalt();
SecretKeyFactory=SecretKeyFactory.getInstance(“pbewithsha256和256biates-CBC-BC”);
KeySpec spec=new-PBEKeySpec(sKey.toCharArray(),salt,1024256);
SecretKey tmp=工厂生成信任(规范);
SecretKey secret=newsecretkeyspec(tmp.getEncoded(),“AES”);
//字节[]bCipherText=base64已解码(EncryptMsg);
//六角形
字节[]bCipherText=toByte(EncryptMsg);
Cipher Cipher=Cipher.getInstance(“AES/CBC/PKCS5Padding”);
cipher.init(cipher.ENCRYPT_模式,secret);
cipher.doFinal(bCipherText);
返回新字符串(bCipherText);
}
私有字节[]getSalt()引发NoSuchAlgorithmException{
/*旧键方法的标记
//初始化密钥生成器
KeyGenerator kgen=KeyGenerator.getInstance(“AES”);
SecureRandom sr=SecureRandom.getInstance(“SHA1PRNG”);
高级种子(种子);
//256bit AES密钥的初始化
kgen.init(Constants.AES_KEY_SIZE,sr);;
SecretKey secret=kgen.generateKey();
//获取秘密原始密钥
字节[]rawKey=secret.getEncoded();
返回rawKey;
*/
//新的关键方法与一些盐
SecureRandom=SecureRandom.getInstance(“SHA1PRNG”);
字节[]ransalt=新字节[20];
随机。下个字节(ransalt);
返回ransalt;
}
@凌驾
公共字节[]getRawKey(字节[]种子)引发异常{
/*旧方法
//初始化密钥生成器
KeyGenerator kgen=KeyGenerator.getInstance(“AES”);
SecureRandom sr=SecureRandom.getInstance(“SHA1PRNG”);
高级种子(种子);
//256bit AES密钥的初始化
kgen.init(常数.AES\u键大小,sr);
SecretKey secret=kgen.generateKey();
//获取秘密原始密钥
字节[]rawKey=secret.getEncoded();
返回rawKey;
*/
返回null;
}
/**
*
*@param-tobedecode
*@返回
*/
公共字节[]base64已解码(字符串待编码){
字节[]decoded=Base64.decode(toBeDecoded,0);
返回解码;
}
//十六进制模式
公共字符串到十六进制(字符串txt){
返回到hex(txt.getBytes());
}
公共字符串fromHex(字符串十六进制){
返回新字符串(toByte(hex));
}
公共字节[]到字节(字符串hexString){
int len=hexString.length()/2;
字节[]结果=新字节[len];
对于(int i=0;i>4)和0x0f)).append(十六进制字符(b和0x0f));
}
}
我在Stackoverflow上引用/比较了以下代码:
及
似乎我的问题在于字符集编码,但我无法找出问题所在
非常感谢您的任何评论/回答!
谢谢你帮助我 我写的这段代码完美无瑕。请看下面的链接: 在不仔细查看代码的情况下,我建议您在此处指定编码,尽管我不确定这是否是问题的原因:
byte[] cipherText = cipher.doFinal(PlainMsg.getBytes());
在这里:
return new String(bCipherText);
我写的这段代码完美无瑕。请看下面的链接: 在不仔细查看代码的情况下,我建议您在此处指定编码,尽管我不确定这是否是问题的原因:
byte[] cipherText = cipher.doFinal(PlainMsg.getBytes());
在这里:
return new String(bCipherText);
谢谢,但是我已经尝试指定了编码方法,但是仍然无法得到正确的结果。然后我删除了所有的代码,并做了一个简单的重新编写,这一次同样的代码工作。