最近有个商城项目为了安全性,要求登录密码,支付密码使用AES 256 位 对称加密,于是就和后台一起搞了下!注(我们后台是用Java写的)
具体参考:具体参考
下载jce_policy-8.zip 链接:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下载jce_policy-6.zip 链接:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
两者选择其中一个就行
下载解压后将里边的两个jar包(local_policy.jar,US_export_policy.jar)替换掉jdk安装路径下security文件夹中的两个包。
两种不同操作系统安装路径:/lib/security [Unix] \lib\security [Windows]
bcprov-jdk15on-156.jar下载链接: http://www.bouncycastle.org/latest_releases.html
直接放在android studio的libs 下编译一下
之后就开始使用代码调用了
android 调用
//我是代码
import android.util.Base64;
import android.util.Log;
import com.elmsc.buyer.Constant;
import java.security.Key;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* 密码加密解密工具类
* 设置登录及钱包支付密码要用
* 采用的是Base64+AES加密方式
* Constant.RES_KEY 和服务器上的一样,要和服务器做交互 key 是base64后的 加密后的串也是base64后的
*/
public class AES256Encryption {
/**
* 密钥算法
* java6支持56位密钥,bouncycastle支持64位
* */
private static final String KEY_ALGORITHM = "AES";
/**
* 加密/解密算法/工作模式/填充方式
* JAVA6 支持PKCS5PADDING填充方式
* Bouncy castle支持PKCS7Padding填充方式
* */
private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS7Padding";
/**
* 生成密钥,java6只支持56位密钥,bouncycastle支持64位密钥
* @return byte[] 二进制密钥
* */
private static byte[] initkey() throws Exception {
// 实例化密钥生成器
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
// 初始化密钥生成器,AES要求密钥长度为128位、192位、256位
kg.init(256);
// kg.init(128);
// 生成密钥
SecretKey secretKey = kg.generateKey();
// 获取二进制密钥编码形式
return secretKey.getEncoded();
// 为了便于测试,这里我把key写死了,如果大家需要自动生成,可用上面注释掉的代码
// return new byte[] { 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c, 0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07,
// 0x0a, 0x04, 0x0f, 0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09, 0x06, 0x07, 0x09, 0x0d };
}
/**
* 转换密钥
* @param key 二进制密钥
* @return Key 密钥
* */
private static Key toKey(byte[] key) throws Exception {
// 实例化DES密钥
// 生成密钥
SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
return secretKey;
}
/**
* 加密数据
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密后的数据
* */
private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
// 还原密钥
Key k = toKey(key);
/**
* 实例化
* 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
* Cipher.getInstance(CIPHER_ALGORITHM,"BC")
*/
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
// 初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 解密数据
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密后的数据
* */
private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 欢迎密钥
Key k = toKey(key);
/**
* 实例化
* 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
* Cipher.getInstance(CIPHER_ALGORITHM,"BC")
*/
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 解密
* @author Guocg
* @param newStr base64后的 ,从服务器获取解密成字符串
* @return
* @throws Exception
*/
public static String decrypt(String newStr) throws Exception {
return new String(
AES256Encryption.decrypt(Base64.decode(newStr,Base64.DEFAULT), Base64.decode(Constant.RES_KEY,Base64.DEFAULT)),
"utf-8");
}
/**
* 加密
* @author Guocg
* @param oldStr,本地加密上传
* @return 密文
* @throws Exception
*/
public static String encrypt(String oldStr) throws Exception {
return Base64
.encodeToString(AES256Encryption.encrypt(oldStr.getBytes(), Base64.decode(Constant.RES_KEY,Base64.DEFAULT)),Base64.DEFAULT);
}
//测试
public static void cesi() throws Exception {
String oldStr = "qinfens撒打发第三方";
Log.i("加密", "原文:"+oldStr);
String key;
// key = Base64.encodeToString(AES256Encryption.initkey(),Base64.DEFAULT);
// key = "ivX1m+Ya01lNbJ0kZpuwmcfzDVDohK4Bsu9xaY5NrB8=";
// Log.i("加密", "密钥:"+key);
// 加密数据
String newStr = encrypt(oldStr);
Log.i("加密", "加密后:"+newStr);
// 解密数据
String str = decrypt(newStr);
Log.i("加密","解密后:"+str);
}
}
Java 调用
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.springframework.util.Base64Utils;
public class AES256Encryption {
/**
* 密钥算法
* java6支持56位密钥,bouncycastle支持64位
* */
private static final String KEY_ALGORITHM = "AES";
/**
* 加密/解密算法/工作模式/填充方式
*
* JAVA6 支持PKCS5PADDING填充方式
* Bouncy castle支持PKCS7Padding填充方式
* */
private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS7Padding";
/**
*
* 生成密钥,java6只支持56位密钥,bouncycastle支持64位密钥
* @return byte[] 二进制密钥
* */
private static byte[] initkey() throws Exception {
// 实例化密钥生成器
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
// 初始化密钥生成器,AES要求密钥长度为128位、192位、256位
kg.init(256);
// kg.init(128);
// 生成密钥
SecretKey secretKey = kg.generateKey();
// 获取二进制密钥编码形式
return secretKey.getEncoded();
// 为了便于测试,这里我把key写死了,如果大家需要自动生成,可用上面注释掉的代码
// return new byte[] { 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c, 0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07,
// 0x0a, 0x04, 0x0f, 0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09, 0x06, 0x07, 0x09, 0x0d };
}
/**
* 转换密钥
* @param key 二进制密钥
* @return Key 密钥
* */
private static Key toKey(byte[] key) throws Exception {
// 实例化DES密钥
// 生成密钥
SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
return secretKey;
}
/**
* 加密数据
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密后的数据
* */
private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
// 还原密钥
Key k = toKey(key);
/**
* 实例化
* 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
* Cipher.getInstance(CIPHER_ALGORITHM,"BC")
*/
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
// 初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 解密数据
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密后的数据
* */
private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 欢迎密钥
Key k = toKey(key);
/**
* 实例化
* 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
* Cipher.getInstance(CIPHER_ALGORITHM,"BC")
*/
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* @param args
* @throws UnsupportedEncodingException
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String oldStr = "qinfens撒打发第三方";
System.out.println("原文:"+oldStr);
String key;
// key = Base64Utils.encodeToString(AES256Encryption.initkey());
key = "ivX1m+Ya01lNbJ0kZpuwmcfzDVDohK4Bsu9xaY5NrB8=";
System.out.println("密钥:"+key);
// 加密数据
String newStr = encrypt(oldStr, key);
System.out.println("加密后:"+newStr);
// 解密数据
String str = decrypt(newStr, key);
System.out.println("解密后:"+str);
}
/**
* 解密
* @author Guocg
* @param newStr base64后的
* @param key base64后的
* @return
* @throws Exception
*/
public static String decrypt(String newStr, String key) throws Exception {
return new String(
AES256Encryption.decrypt(Base64Utils.decodeFromString(newStr), Base64Utils.decodeFromString(key)),
"utf-8");
}
/**
* 加密
* @author Guocg
* @param oldStr
* @param key base64后的
* @return
* @throws Exception
*/
public static String encrypt(String oldStr, String key) throws Exception {
return Base64Utils
.encodeToString(AES256Encryption.encrypt(oldStr.getBytes(), Base64Utils.decodeFromString(key)));
}
}
注:如果导包完成后找不到包的话
就在build.gradle添加compile files('libs/bcprov-jdk15on-156.jar')
make完成后删除
诸多不足,希望大神们不吝赐教!