转的JAVA实现AES加密
?
JAVA实现AES加密
1. 因子???????上次介绍了《JAVA实现AES加密》,中间提到近些年DES使用越来越少,原因就在于其使用56位密钥,比较容易被破解,近些年来逐渐被AES替代,AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据。本文就简单介绍如何通过JAVA实现AES加密。2. JAVA实现闲话少许,掠过AES加密原理及算法,关于这些直接搜索专业网站吧,我们直接看JAVA的具体实现。2.1 加密代码有详细解释,不多废话。view plain- /**??*?加密?
- ?*???*?@param?content?需要加密的内容?
- ?*?@param?password??加密密码??*?@return?
- ?*/??public?static?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?static?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;??
- }??
- String?content?=?"test";??String?password?=?"12345678";??
- //加密??System.out.println("加密前:"?+?content);??
- byte[]?encryptResult?=?encrypt(content,?password);??//解密??
- byte[]?decryptResult?=?decrypt(encryptResult,password);??System.out.println("解密后:"?+?new?String(decryptResult));??
解密后:test2.4 容易出错的地方但是如果我们将测试代码修改一下,如下:view plain
- String?content?=?"test";??String?password?=?"12345678";??
- //加密??System.out.println("加密前:"?+?content);??
- byte[]?encryptResult?=?encrypt(content,?password);??try?{??
- ????????String?encryptResultStr?=?new?String(encryptResult,"utf-8");??????????//解密??
- ????????byte[]?decryptResult?=?decrypt(encryptResultStr.getBytes("utf-8"),password);??????????System.out.println("解密后:"?+?new?String(decryptResult));??
- }?catch?(UnsupportedEncodingException?e)?{??????????e.printStackTrace();??
- }??
????????at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
????????at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
????????at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
????????at javax.crypto.Cipher.doFinal(DashoA13*..)这主要是因为加密后的byte数组是不能强制转换成字符串的,换言之:字符串和byte数组在这种情况下不是互逆的;要避免这种情况,我们需要做一些修订,可以考虑将二进制数据转换成十六进制表示,主要有如下两个方法:2.4.1将二进制转换成16进制view plain
- /**将二进制转换成16进制??*?@param?buf?
- ?*?@return??*/??
- public?static?String?parseByte2HexStr(byte?buf[])?{??????????StringBuffer?sb?=?new?StringBuffer();??
- ????????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();??
- }??
- /**将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;??
- }??
- String?content?=?"test";??String?password?=?"12345678";??
- //加密??System.out.println("加密前:"?+?content);??
- byte[]?encryptResult?=?encrypt(content,?password);??String?encryptResultStr?=?parseByte2HexStr(encryptResult);??
- System.out.println("加密后:"?+?encryptResultStr);??//解密??
- byte[]?decryptFrom?=?parseHexStr2Byte(encryptResultStr);??byte[]?decryptResult?=?decrypt(decryptFrom,password);??
- System.out.println("解密后:"?+?new?String(decryptResult));??
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test?2.5 另外一种加密方式还有一种加密方式,大家可以参考如下:view plain
- /**???????*?加密?
- ??????*???????*?@param?content?需要加密的内容?
- ??????*?@param?password??加密密码???????*?@return?
- ??????*/???????public?static?byte[]?encrypt2(String?content,?String?password)?{??
- ?????????????try?{???????????????????????SecretKeySpec?key?=?new?SecretKeySpec(password.getBytes(),?"AES");??
- ?????????????????????Cipher?cipher?=?Cipher.getInstance("AES/ECB/NoPadding");???????????????????????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;???????}??
????????at com.sun.crypto.provider.SunJCE_f.a(DashoA13*..)
????????at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
????????at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
????????at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
????????at javax.crypto.Cipher.doFinal(DashoA13*..)要解决如上异常,可以通过补全传入加密内容等方式进行避免。