AES在Android、JAVA端正常加密解密
2015-11-12 15:50
537 查看
AES在Android、JAVA端正常加密解密,有需要的朋友可以参考下。
<span style="font-size:18px;">public class AESUtil {
static final public byte[] KEY_VI = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8};
public static final String bm = "UTF-8";
public static String encrypt(String dataPassword, String cleartext)
throws Exception {
IvParameterSpec zeroIv = new IvParameterSpec(KEY_VI);
SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
byte[] encryptedData = cipher.doFinal(cleartext.getBytes(bm));
return new String (parseByte2HexStr(encryptedData));
}
public static String decrypt(String dataPassword, String encrypted)
throws Exception {
byte[] byteMi = parseHexStr2Byte(encrypted);
IvParameterSpec zeroIv = new IvParameterSpec(KEY_VI);
SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
byte[] decryptedData = cipher.doFinal(byteMi);
return new String(decryptedData,bm);
}
/**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* 将二进制转换成16进制
*
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
}
使用上面的方法android和Java端都可以可以正常加密解密。但是密钥必须是16,24或者32位。因为:
AES supports 128, 192 and 256 bit keys, so the number of bytes needs to be 16, 24, or 32. Note that the latter two may not be available in all circumstances (as the comment in the "kgen.init(128)" line mentions).
当密钥不是16,24,32位的时候就需要我们来做处理了
public class AESUtil {
static final public byte[] KEY_VI = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
public static final String bm = "UTF-8";
public static String encrypt(String dataPassword, String cleartext) throws Exception {
// 对密钥进行处理-S
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom;
// for Android
secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
// for Java
// secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(dataPassword.getBytes("UTF-8"));
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
// 对密钥进行处理-E
IvParameterSpec zeroIv = new IvParameterSpec(KEY_VI);
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
byte[] encryptedData = cipher.doFinal(cleartext.getBytes(bm));
return new String(parseByte2HexStr(encryptedData));
}
public static String decrypt(String dataPassword, String encrypted) throws Exception {
// 对密钥进行处理-S
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom;
// for Android
secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
// for Java
// secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(dataPassword.getBytes("UTF-8"));
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
// 对密钥进行处理-E
byte[] byteMi = parseHexStr2Byte(encrypted);
IvParameterSpec zeroIv = new IvParameterSpec(KEY_VI);
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
byte[] decryptedData = cipher.doFinal(byteMi);
return new String(decryptedData, bm);
}
/**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* 将二进制转换成16进制
*
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
}</span>Android和Java端的区别在于处理后的密钥enCodeFormat不同,导致Android端加密后的数据传递到Java端,在Java端不能正常解密。同理Java端加密的数据也没法在Android端正常解密
<span style="font-size:18px;">public class AESUtil {
static final public byte[] KEY_VI = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8};
public static final String bm = "UTF-8";
public static String encrypt(String dataPassword, String cleartext)
throws Exception {
IvParameterSpec zeroIv = new IvParameterSpec(KEY_VI);
SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
byte[] encryptedData = cipher.doFinal(cleartext.getBytes(bm));
return new String (parseByte2HexStr(encryptedData));
}
public static String decrypt(String dataPassword, String encrypted)
throws Exception {
byte[] byteMi = parseHexStr2Byte(encrypted);
IvParameterSpec zeroIv = new IvParameterSpec(KEY_VI);
SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
byte[] decryptedData = cipher.doFinal(byteMi);
return new String(decryptedData,bm);
}
/**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* 将二进制转换成16进制
*
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
}
使用上面的方法android和Java端都可以可以正常加密解密。但是密钥必须是16,24或者32位。因为:
AES supports 128, 192 and 256 bit keys, so the number of bytes needs to be 16, 24, or 32. Note that the latter two may not be available in all circumstances (as the comment in the "kgen.init(128)" line mentions).
当密钥不是16,24,32位的时候就需要我们来做处理了
public class AESUtil {
static final public byte[] KEY_VI = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
public static final String bm = "UTF-8";
public static String encrypt(String dataPassword, String cleartext) throws Exception {
// 对密钥进行处理-S
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom;
// for Android
secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
// for Java
// secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(dataPassword.getBytes("UTF-8"));
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
// 对密钥进行处理-E
IvParameterSpec zeroIv = new IvParameterSpec(KEY_VI);
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
byte[] encryptedData = cipher.doFinal(cleartext.getBytes(bm));
return new String(parseByte2HexStr(encryptedData));
}
public static String decrypt(String dataPassword, String encrypted) throws Exception {
// 对密钥进行处理-S
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom;
// for Android
secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
// for Java
// secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(dataPassword.getBytes("UTF-8"));
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
// 对密钥进行处理-E
byte[] byteMi = parseHexStr2Byte(encrypted);
IvParameterSpec zeroIv = new IvParameterSpec(KEY_VI);
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
byte[] decryptedData = cipher.doFinal(byteMi);
return new String(decryptedData, bm);
}
/**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* 将二进制转换成16进制
*
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
}</span>Android和Java端的区别在于处理后的密钥enCodeFormat不同,导致Android端加密后的数据传递到Java端,在Java端不能正常解密。同理Java端加密的数据也没法在Android端正常解密
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法