请教下android下的AES加密和解密(加密正常,解密失败) 本帖最后由 cy757 于 2013-10-18 10:29:30 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 /** 以下是DES算法封装类 */package security;import java.security.Key;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public class DES { private Key key; public DES(String strkey) { setKey(strkey); } public DES() { setKey("areful"); } /** * 获取密钥 */ public String getKey() throws Exception { return Base64Utils.encode(key.getEncoded()); } /** * 根据参数生成KEY */ public void setKey(String strKey) { try { KeyGenerator _generator = KeyGenerator.getInstance("DES"); _generator.init(new SecureRandom(strKey.getBytes())); this.key = _generator.generateKey(); _generator = null; } catch (Exception e) { throw new RuntimeException( "Error initializing SqlMap class. Cause: " + e); } } /** * 加密String明文输入,String密文输出 */ public String getEncString(String strMing) { byte[] byteMi = null; byte[] byteMing = null; String strMi = ""; BASE64Encoder base64en = new BASE64Encoder(); try { byteMing = strMing.getBytes("UTF8"); byteMi = this.getEncCode(byteMing); strMi = base64en.encode(byteMi); } catch (Exception e) { throw new RuntimeException( "Error initializing SqlMap class. Cause: " + e); } finally { base64en = null; byteMing = null; byteMi = null; } return strMi; } /** * 解密 以String密文输入,String明文输出 * * @param strMi * @return */ public String getDesString(String strMi) { BASE64Decoder base64De = new BASE64Decoder(); byte[] byteMing = null; byte[] byteMi = null; String strMing = ""; try { byteMi = base64De.decodeBuffer(strMi); byteMing = this.getDesCode(byteMi); strMing = new String(byteMing, "UTF8"); } catch (Exception e) { throw new RuntimeException( "Error initializing SqlMap class. Cause: " + e); } finally { base64De = null; byteMing = null; byteMi = null; } return strMing; } /** * 加密以byte[]明文输入,byte[]密文输出 * * @param byteS * @return */ private byte[] getEncCode(byte[] byteS) { byte[] byteFina = null; Cipher cipher; try { cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key); byteFina = cipher.doFinal(byteS); } catch (Exception e) { throw new RuntimeException( "Error initializing SqlMap class. Cause: " + e); } finally { cipher = null; } return byteFina; } /** * 解密以byte[]密文输入,以byte[]明文输出 * * @param byteD * @return */ private byte[] getDesCode(byte[] byteD) { Cipher cipher; byte[] byteFina = null; try { cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key); byteFina = cipher.doFinal(byteD); } catch (Exception e) { throw new RuntimeException( "Error initializing SqlMap class. Cause: " + e); } finally { cipher = null; } return byteFina; }}/** 以下是DES封装类的测试类 */package test;import security.DES;public class TestDES { public static void main(String[] args) { TestDES t = new TestDES(); t.test(); } private void test() { DES des = new DES(); // 设置密钥 // des.setKey("12345678"); String str1 = "加密前的字符串"; // DES加密 String str2 = des.getEncString(str1); String deStr = des.getDesString(str2); System.out.println("密文:" + str2); // DES解密 System.out.println("明文:" + deStr); }} /** 比一下,看看少什么东西 */package security;import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;public class AES { /** * 加密 * * @param content 需要加密的内容 * @param password 加密密码 * @return */ public byte[] encrypt(String content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 byte[] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(byteContent); return result; // 加密 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; } /**解密 * @param content 待解密内容 * @param password 解密密钥 * @return */ public byte[] decrypt(byte[] content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 cipher.init(Cipher.DECRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(content); return result; // 加密 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; }} 谢谢areful大哥,不过奇怪了areful大哥你的代码也不行。现在也搞不懂是什么原因了,查了一下网上很多反映解密失败的。但是就没人说是什么原因,刚刚学android,被这个搞得晕头转向。 楼主,你的android解密问题解决没??? android 版本问题4.2以上好像会有问题。 你加密的是不是服务器端,解密的是不是手机端?我以前也遇到过这样的问题,服务器端加密的东西然后手机端就无法解密,报异常,原因好像是Cipher设置的不一致,你下载一个有关加密设置的文档看一下,还需要设置一个IvParameterSpecprivate static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };IvParameterSpec zeroIv = new IvParameterSpec(iv);cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);具体你再查查资料吧,如果实在不行,我晚上回家把资料帖出来。 package com.shine.analogoscilloscope;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import android.app.Activity;import android.os.Bundle;public class AESActivity extends Activity { private final static String HEX = "0123456789ABCDEF"; public static String encrypt(String seed, String cleartext) throws Exception { byte[] rawKey = getRawKey(seed.getBytes()); byte[] result = encrypt(rawKey, cleartext.getBytes()); return toHex(result); } public static String decrypt(String seed, String encrypted) throws Exception { byte[] rawKey = getRawKey(seed.getBytes()); byte[] enc = toByte(encrypted); byte[] result = decrypt(rawKey, enc); return new String(result); } public static 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; } private static byte[] getRawKey(byte[] seed) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); sr.setSeed(seed); kgen.init(128, sr); // 192 and 256 bits may not be available SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); return raw; } private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(clear); return encrypted; } private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte[] decrypted = cipher.doFinal(encrypted); return decrypted; } public static String toHex(String txt) { return toHex(txt.getBytes()); } public static String fromHex(String hex) { return new String(toByte(hex)); } public static 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 static void appendHex(StringBuffer sb, byte b) { sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.aes_main); String masterPassword = "a"; String originalText = "0123456789"; try { System.out.println("加密文本为" + originalText); String encryptingCode = AESActivity.encrypt(masterPassword, originalText); System.out.println("加密结果为 " + encryptingCode); String decryptingCode = AESActivity.decrypt(masterPassword, encryptingCode); System.out.println("解密结果为 " + decryptingCode); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }} 这个问题还是我来终结吧,4.2之后SHA1PRNG 强随机种子算法调用方法不同,可用以下方式区别调用private static byte[] getRawKey(byte[] seed) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); // SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法 SecureRandom sr = null; if (android.os.Build.VERSION.SDK_INT >= 17) { sr = SecureRandom.getInstance("SHA1PRNG", "Crypto"); } else { sr = SecureRandom.getInstance("SHA1PRNG"); } sr.setSeed(seed); kgen.init(256, sr); //256 bits or 128 bits,192bits SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); return raw; } 帖子好给力!之前也是AES解密,在android2.3上测试可行,在4.4版本就解密失败。看了Eclipse的警告,说是什么随机数只适用于android4.3之前的。到这儿看了大神回答,茅塞顿开 ?123456789101112131415private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(clear); return encrypted; } AES的几种模式,考虑清楚后就验证,不行的话,就通过中间服务获取加密和解密结果。 大神求教,我用AES加密图片 ,在解密后打开图片显示无缩略图,该怎么破 如何修改android虚拟机的MEID号呢? 关于ZIP压缩问题 各位帮忙看看如何解决 如何打开一条刚刚收到的短信 在线求助,关于软键盘弹出,Dialog布局被改变的问题。 在xml静态布局中,如何动态地更新加在该布局中的一个自定义view 关于json转化成集合 将Activity打包成jar包后无法正常调用,求助! [求教]怎样为Android Library项目打包 android 调试问题,ART调试,ART模式,大家来说说 萌新求救girdview 如何分别生成中英的javadoc android listview如何显示sqlite中的数据
package security;import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;public class DES {
private Key key; public DES(String strkey) {
setKey(strkey);
} public DES() {
setKey("areful");
} /**
* 获取密钥
*/
public String getKey() throws Exception {
return Base64Utils.encode(key.getEncoded());
}
/**
* 根据参数生成KEY
*/
public void setKey(String strKey) {
try {
KeyGenerator _generator = KeyGenerator.getInstance("DES");
_generator.init(new SecureRandom(strKey.getBytes()));
this.key = _generator.generateKey();
_generator = null;
} catch (Exception e) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
}
} /**
* 加密String明文输入,String密文输出
*/
public String getEncString(String strMing) {
byte[] byteMi = null;
byte[] byteMing = null;
String strMi = "";
BASE64Encoder base64en = new BASE64Encoder();
try {
byteMing = strMing.getBytes("UTF8");
byteMi = this.getEncCode(byteMing);
strMi = base64en.encode(byteMi);
} catch (Exception e) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
} finally {
base64en = null;
byteMing = null;
byteMi = null;
}
return strMi;
} /**
* 解密 以String密文输入,String明文输出
*
* @param strMi
* @return
*/
public String getDesString(String strMi) {
BASE64Decoder base64De = new BASE64Decoder();
byte[] byteMing = null;
byte[] byteMi = null;
String strMing = "";
try {
byteMi = base64De.decodeBuffer(strMi);
byteMing = this.getDesCode(byteMi);
strMing = new String(byteMing, "UTF8");
} catch (Exception e) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
} finally {
base64De = null;
byteMing = null;
byteMi = null;
}
return strMing;
} /**
* 加密以byte[]明文输入,byte[]密文输出
*
* @param byteS
* @return
*/
private byte[] getEncCode(byte[] byteS) {
byte[] byteFina = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byteFina = cipher.doFinal(byteS);
} catch (Exception e) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
} finally {
cipher = null;
}
return byteFina;
} /**
* 解密以byte[]密文输入,以byte[]明文输出
*
* @param byteD
* @return
*/
private byte[] getDesCode(byte[] byteD) {
Cipher cipher;
byte[] byteFina = null;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byteFina = cipher.doFinal(byteD);
} catch (Exception e) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
} finally {
cipher = null;
}
return byteFina;
}
}/** 以下是DES封装类的测试类 */
package test;import security.DES;public class TestDES {
public static void main(String[] args) {
TestDES t = new TestDES(); t.test();
} private void test() {
DES des = new DES();
// 设置密钥
// des.setKey("12345678");
String str1 = "加密前的字符串";
// DES加密
String str2 = des.getEncString(str1);
String deStr = des.getDesString(str2);
System.out.println("密文:" + str2);
// DES解密
System.out.println("明文:" + deStr); }
}
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;public class AES {
/**
* 加密
*
* @param content 需要加密的内容
* @param password 加密密码
* @return
*/
public byte[] encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return result; // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**解密
* @param content 待解密内容
* @param password 解密密钥
* @return
*/
public byte[] decrypt(byte[] content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
return result; // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
}
我以前也遇到过这样的问题,服务器端加密的东西然后手机端就无法解密,报异常,原因好像是Cipher设置的不一致,你下载一个有关加密设置的文档看一下,还需要设置一个IvParameterSpec
private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };
IvParameterSpec zeroIv = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
具体你再查查资料吧,如果实在不行,我晚上回家把资料帖出来。
package com.shine.analogoscilloscope;import java.security.SecureRandom;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;import android.app.Activity;
import android.os.Bundle;public class AESActivity extends Activity { private final static String HEX = "0123456789ABCDEF"; public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
} public static String decrypt(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
} public static 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;
} private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
} private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
} private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
} public static String toHex(String txt) {
return toHex(txt.getBytes());
} public static String fromHex(String hex) {
return new String(toByte(hex));
} public static 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 static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
} /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aes_main);
String masterPassword = "a";
String originalText = "0123456789";
try {
System.out.println("加密文本为" + originalText);
String encryptingCode = AESActivity.encrypt(masterPassword, originalText);
System.out.println("加密结果为 " + encryptingCode);
String decryptingCode = AESActivity.decrypt(masterPassword, encryptingCode);
System.out.println("解密结果为 " + decryptingCode);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
// SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法
SecureRandom sr = null;
if (android.os.Build.VERSION.SDK_INT >= 17) {
sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
} else {
sr = SecureRandom.getInstance("SHA1PRNG");
}
sr.setSeed(seed);
kgen.init(256, sr); //256 bits or 128 bits,192bits
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}