Java AES实现对称加密
前言:
AES:高级加密标准(英语:Advanced Encryption Standard,缩写:AES),这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用,AES的优势之一是至今尚未被破解。AES通常用于移动通信系统加密以及基于SSH协议的软件。
测试:
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
import org.junit.Test;public class testAES {@Testpublic void AES() {try {String middleKey = "123456"; //就是所谓的密钥,加密和解密双方都需要String password = "kevin"; //需要被加密的内容// 生成KEYKeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(new SecureRandom(middleKey.getBytes()));SecretKey secretKey = keyGenerator.generateKey();byte[] byteKey = secretKey.getEncoded();Key key = new SecretKeySpec(byteKey, "AES");// 加密Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, key);byte[] result = cipher.doFinal(password.getBytes());System.out.println("加密后:" + Hex.encodeHexString(result));// 解密cipher.init(Cipher.DECRYPT_MODE, key);result = cipher.doFinal(result);System.out.println("解密后:" + new String(result));} catch (Exception e) {e.printStackTrace();}}
}
运行结果如下:

编写工具类:
AesUtils:
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;public class AesUtils {private final String MiddleKey = "123456";//生成key需要的密码public String encrypt(String password) {try {// 加密Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, getKey());byte[] result = cipher.doFinal(password.getBytes());// return Hex.encodeHexString(result); return Base64.encodeBase64String(result);//通过Base64转码返回} catch (Exception e) {e.printStackTrace();}return "";}/** encryptedPassword:待解密的密文*/public String decrypt(String encryptedPassword) {try {// 解密Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, getKey());// byte[] result = cipher.doFinal(encryptedPassword.getBytes());byte[] result = cipher.doFinal(Base64.decodeBase64(encryptedPassword));return new String(result);} catch (Exception e) {e.printStackTrace();}return "";}private Key key;public Key getKey() {if (key == null) {try {// 生成KEY ,AES 要求密钥长度为 128KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(MiddleKey.getBytes());keyGenerator.init(128,secureRandom);SecretKey secretKey = keyGenerator.generateKey();byte[] byteKey = secretKey.getEncoded();// 转换KEYkey = new SecretKeySpec(byteKey, "AES");return key;} catch (Exception e) {e.printStackTrace();return null;}} else {return key;}}
}
使用:
public void main() {AesUtils aesUtils=new AesUtils();String encryptStr = aesUtils.encrypt("hello world");System.out.println("加密后的结果:"+ encryptStr);String decryptStr = aesUtils.decrypt(encryptStr);System.out.println("解密后的结果:"+ decryptStr);}
运行结果如下:

问题:
1.AesUtils中加密和加密函数中分别有一句被注释的代码,然后改成了base64转码,这是因为使用注释的代码在解密的时候会报错:
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption. at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991)
原因是直接用tostring 和getbytes方法操作 加密后的byte [ ] 会丢失信息
解决方案就是:
要么使用Base64来转码
要么像上方Test方法中一样,直接用byte [ ]去解密
2.在windows下能正常解密,但是相同的代码拷贝到linux下既失效。
解决方法:把getkey中的初始化SecureRandom,改成如下方式即可:
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(MiddleKey.getBytes());keyGenerator.init(128,secureRandom);
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
