高性能AES256对称加解密,兼容Java、IOS、Android

时间:2022-05-16 18:29:01

最近在设计一个给IOS和Android提供接口的项目框架,在接口安全上准备使用常规的加密技术,确保在非法访问接口的情况下拿到的数据一时半会也没用。

查了相关的资料,用的最多的几种加密算法,DES、AES、3DES等,考虑到手机端的兼容,先用了DES。但我遇到一个现象后,让我决定放弃DES,不知道有没有大神也遇到过,就是我用DES加密后,再用AES加密DES解密后的内容。拿到密文后使用AES反过来解密,结果AES一次解密后就得到了两次加密前的明文。为了排除是内存的问题,我特地在A机器上加密,B机器上解密,结果还是坑爹的一样。为了节省时间就没有细细的研究了,有时间了再细细研究。

最后决定选用AES,密钥长度为128位作为加解密工具,在与前端联调的发现了个问题,就是服务器加密的数据,客户端无法解密。经过研究发现,是由于IOS加密填充方式是PKCS7Padding和而服务器使用的加密填充方式是PKCS5Padding,只支持56位密钥。查询资料后发现使用AES密钥为256位加密后在客户端可以正常的解密。但有个问题,就是我使用的JDK1.6自带的security是不支持256位的。这个使用可以使用Bouncy castle,它支持PKCS7Padding的64位算法。

下面说说具体的实现办法:

1、声明密钥算法

public static final String KEY_ALGORITHM="AES"; 

2、声明加密填充方式

public static final String CIPHER_ALGORITHM="AES/ECB/PKCS7Padding"; 

3、生成密钥,生成的密钥原本是byte[]类型,为了对密钥进行在加工,这里我用Base64加密了一次,如果不要的这里可以直接返回byte[]

public static String initkey() throws Exception{
//实例化密钥生成器
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
<span style="white-space:pre"></span>//初始化密钥生成器,AES要求密钥长度为128位、192位、256位
kg.init(256);
//生成密钥
SecretKey secretKey=kg.generateKey();
//获取二进制密钥编码形式
return Base64.encode(secretKey.getEncoded());
}
4、密钥转换

public static Key toKey(byte[] key) throws Exception{
//实例化DES密钥
//生成密钥
SecretKey secretKey=new SecretKeySpec(key,KEY_ALGORITHM);
return secretKey;
}
5、加密方法,跟生成密钥一样,对传参部分进行了处理

public static String encrypt(String data,String key) throws Exception{
byte[] keys = Base64.decode(key);
//还原密钥
Key k=toKey(keys);
/**
* 实例化
* 使用 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 Base64.encode(cipher.doFinal(data.getBytes()));
}
5、解密数据

public static String decrypt(String data,String key) throws Exception{
byte[] datas = Base64.decode(data);
byte[] keys = Base64.decode(key);
//欢迎密钥
Key k =toKey(keys);
/**
* 实例化
* 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
* Cipher.getInstance(CIPHER_ALGORITHM,"BC")
*/
Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
//初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, k);
//执行操作
return new String(cipher.doFinal(datas));
}
6、Main方法测试

public static void main(String[] args) throws UnsupportedEncodingException{
String str="DaddyCai";
System.out.println("原文:"+str);
try {
//初始化密钥
String key = AES256Encryption.initkey();
System.out.println("密钥:"+key);
//加密数据
String data=AES256Encryption.encrypt(str, key);
System.out.println("加密后:"+data);
//解密数据
System.out.println("解密后:"+AES256Encryption.decrypt(data, key));
} catch (Exception e) {
e.printStackTrace();
}
}

到这里,一个简单的加解密算法就算实现了,这里有点要注意:jdk自带的security不能生成64位密钥,需要替换原jdk下security的两个文件。以上代码仅供大家研究测试,完整代码可以在这里下载!

下载地址:http://download.csdn.net/download/localhost_8080/8551677