- 浏览: 572454 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
liuzeyuss:
好文章,顶顶
java 线程死锁的检测 -
ysite:
hugh.wang 写道请问你这个能还原吗?短网址用的是HAS ...
Java版短网址(ShortUrl)的算法 -
lv双:
没有注释,看的费劲
java 线程死锁的检测 -
dgj:
好帖子竟然没人顶...
java 线程死锁的检测 -
天空趋虚:
不好,你这只是记录式的博客,不是分享式的博客,对浏览着不友好. ...
一些技术牛人的博客
转的JAVA实现AES加密
- 博客分类:
- J2SE
JAVA实现AES加密
1. 因子
上次介绍了《JAVA实现AES加密
》,
中间提到近些年DES使用越来越少,原因就在于其使用56位密钥,比较容易被破解,近些年来逐渐被AES替代,AES已经变成目前对称加密中最流行算法之
一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据。本文就简单介绍如何通过JAVA实现AES加密。
2. JAVA实现
闲话少许,掠过AES加密原理及算法,关于这些直接搜索专业网站吧,我们直接看JAVA的具体实现。
2.1 加密
代码有详细解释,不多废话。
- /**
- * 加密
- *
- * @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 ;
- }
2.2 解密
代码有详细注释,不多废话
注意:解密的时候要传入byte数组
- /**解密
- * @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 ;
- }
2.3 测试代码
- 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));
输出结果如下:
加密前:test
解密后:test
解密后:test
2.4 容易出错的地方
但是如果我们将测试代码修改一下,如下:
- 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();
- }
则,系统会报出如下异常:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
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*..)
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进制
- /**将二进制转换成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();
- }
2.4.2 将16进制转换为二进制
- /**将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));
测试结果如下:
加密前:test
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test
2.5 另外一种加密方式
还有一种加密方式,大家可以参考如下:
- /**
- * 加密
- *
- * @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 ;
- }
这种加密方式有两种限制
- 密钥必须是16位的
- 待加密内容的长度必须是16的倍数,如果不是16的倍数,就会出如下异常:
javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
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*..)
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*..)
要解决如上异常,可以通过补全传入加密内容等方式进行避免。
发表评论
-
卧槽,我为netty贡献过代码,牛比不?
2014-02-14 10:15 1008发现netty有一段代码怎么跟我写的似的呢?一看github才 ... -
约瑟夫出圈问题
2012-02-21 15:48 1676import java.util.Scanner; ... -
书单,觉得比较好的书单 。
2012-01-28 11:29 1979学习软件开发应该看 ... -
去掉小箭头
2011-12-31 11:25 1002http://jingyan.baidu.com/articl ... -
Eclipse下使用Xfire创建WebService入门示例(转)
2011-12-19 16:21 1821什么是Web Service Web Se ... -
JAVA String.format 方法使用介绍
2011-10-25 18:25 8571.对整数进行格式化:%[index$][标识][最小宽度]转 ... -
处理系统全变成lnk图标的方法
2011-10-23 16:57 1518相信有些用户曾试过错误地把LNK文件的打开方式更改其他文件,导 ... -
如何读写json文件
2011-10-09 15:43 18594代码如下: import java.io.Buffered ... -
log4J的学习
2011-10-09 13:28 912http://blog.csdn.net/eako/artic ... -
linux下安装jsk
2011-10-08 18:55 11471. 去http://java.sun.com ... -
一些技术牛人的博客
2011-08-30 13:23 2369High Scalability - Building big ... -
把一个xml节点信息递归的存到map中的方法
2011-05-27 16:52 3673jar包自己加!! import java.util.Ha ... -
关于java中的static{}块
2011-04-29 15:38 4604一直以来对static块不是很熟系,今天特意写了两个程序来搞清 ... -
大数相加的java实现
2011-04-06 17:43 1695import java.io.BufferedReader ... -
java中的逻辑移位与算数移位
2011-03-22 14:12 1798java中是支持逻辑移位和算数移位的,简单说,逻辑移位就是不带 ... -
关于短路与和非短路与 (&& 和&)
2011-03-22 11:55 2594这两个操作符都是与的意思 && 和 ... -
java基础类型
2011-03-22 11:16 933java含有四类八种基本的数据类型。 首先是整型, 1,byt ... -
java命令参数
2011-03-20 22:07 1192Java命令参数说明大全 ... -
线程之间通信的三种方法
2011-03-17 15:50 3217线程间通信的三种方法 ... -
java中抽象类和接口详解
2011-03-07 11:01 1061在Java语言中, abstract class 和int ...
相关推荐
java实现aes加解密
Java实现AES加密算法Java实现AES加密算法
Java AES加密Java AES加密Java AES加密Java AES加密Java AES加密Java AES加密Java AES加密
本文就简单介绍如何通过JAVA实现AES加密: /** * 测试AES加密和解密 * @param args */ public static void main(String[] args) { /**数据初始化**/ String content = "http://www.mbaike.net"; String...
1.采用秘钥为16位长度的加密字符 2.加密算法为AES/ECB/PKCS5Padding 3.解决加解密乱码问题 4.完整的线上可运行代码及各方法及步骤注释 5.无任何插件,java环境直接运行
主要介绍了java使用Hex编码解码实现Aes加密解密功能,结合完整实例形式分析了Aes加密解密功能的定义与使用方法,需要的朋友可以参考下
AES高级加密标准,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种...本软件是用java语言开发,实现了AES算法对文件的加密和解密,并在界面上加了进度条,来提示用户加密解密的进度。如果不足之处,欢迎留言。
在工作中会经常遇到密码加密,URL传参要进行加密,在此我参照一个例子将用java实现的AES加解密程序用实例写出。JS实现AES-GCM加密,java实现AES-GCM解密
JAVA实现AES加密算法代码.doc
java代码-java使用AES加密解密 AES-128-ECB加密 ——学习参考资料:仅用于个人学习使用
采用固定AES密钥加密,AES使用PKCS5规则进行补位,加密模式使用AES-ECB
使用JAVA实现的AES算法,代码通俗易懂,方便初学者对AES进行研究与学习
压缩包里有两个工程,一个vc6.0一个myeclipse,本帖是修复贴,原帖地址c/c++ 与java互通 AES加密解密,算法ECB/PKCS5PADDING http://download.csdn.net/download/wangsonghiweed/4328267 -来自CSDN,有童鞋反映有...
AES加密算法的JAVA实现(只有加密)
Delphi实现AES加密和解密, 同Java加解密兼容
java 基于AES实现对文件的加密 解密 有问题 www.willvc.com.cn 能联系到我
java实现aes加密,采用cbc模式,PKCS5Padding填充,key ALLINPAYRISKERR0,偏移量IV 0000000000000000,hex输出 。
c/c++与java互通 AES加密解密; 只使用基本char,数组运算实现加密算法;不依赖其它加密lib
AES加密的两种方式。一种String 一种byte。并且添加进制转换解决加密过程非法报错问题
本案例使用springboot进行快速构建项目,AES进行对称加密及解密