java封装AES加密算法
在实际coding中会常常遇到往数据库存入密码时加密。URL传參时的加密。由此简单封装了下java中的AES加密算法。
0、import类
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.axis.encoding.Base64; //非必须
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 (Exception e) {
e.printStackTrace();
}
return null;
}
2、解密接口
/**解密
* @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 (Exception e) {
e.printStackTrace();
}
return null;
}
3、编解码函数(非必须)
//编码函数
public static String encode(String content, String key) throws Exception {
byte[] encrypt = encrypt(content, key);
return Base64.encode(encrypt);
}
//解码函数
public static String decode(String encode, String key) throws Exception {
byte[] encrypt = Base64.decode(encode);
byte[] content = decrypt(encrypt, key);
return new String(content);
}
4、測试
//0-正常使用
public static void main(String[] args) throws Exception{
String content = "holybin";
String password = "12345678";
System.out.println("加密前1:" + content);
byte[] encryptResult1 = encrypt(content, password); //普通加密
byte[] decryptResult1 = decrypt(encryptResult1,password); //普通解密
System.out.println("解密后1:" + new String(decryptResult1));
System.out.println("\n加密前2:" + content);
String encryptResult2 = encode(content, password); //先编码再加密
System.out.println("加密后2:" + encryptResult2);
String decryptResult2 = decode(encryptResult2, password); //先解码再解密
System.out.println("解密后2:" + decryptResult2);
}
结果例如以下:
5、问题与思考
(1)普通加密后将得到的byte数组直接转化为字符串用于输出,或者普通解密时从字符串转换为byte数组用于传參会发生什么?
//1-先測试加密
public static void main(String[] args) throws Exception{
String content = "holybin";
String password = "12345678";
System.out.println("加密前1:" + content);
byte[] encryptResult1 = encrypt(content, password); //普通加密
System.out.println("加密后1:" + encryptResult1);
System.out.println("加密后1:" + new String(encryptResult1));
byte[] decryptResult1 = decrypt(encryptResult1,password); //普通解密
System.out.println("解密后1:" + new String(decryptResult1));
}
结果1:
这里将加密后的byte数组直接转化成String输出。出现乱码。
//2-再測试解密
public static void main(String[] args) throws Exception{
String content = "holybin";
String password = "12345678";
System.out.println("加密前1:" + content);
byte[] encryptResult1 = encrypt(content, password); //普通加密
String strEncryptResult1 = new String(encryptResult1,"UTF-8");
//System.out.println("加密后1:" + strEncryptResult1);
byte[] decryptResult1 = decrypt(strEncryptResult1.getBytes("UTF-8"),password); //普通解密
System.out.println("解密后1:" + new String(decryptResult1));
}
结果2:
这里从加密后的String提取bytes数组用于解密,出现报错
原因:主要是由于加密后的byte数组是不能强制转换成字符串的,加密过的字符串也不能直接提取bytes数组用于解密,解决方法有两个:一是像上面測试的样例一样先加密再编码,或先解码再解密(參考:4、測试)。二是採用十六进制和二进制的相互转化函数(參考:以下的第(2)点)。
(2)十六进制和二进制相互转化函数
// 二进制转十六进制
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();
}
// 十六进制转二进制
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;
}
使用演示样例:
// 3-測试转化函数
public static void main(String[] args) throws Exception {
String content = "holybin";
String password = "12345678";
//加密
System.out.println("加密前1:" + content);
byte[] encryptResult = encrypt(content, password); // 普通加密
String strEncryptResult = parseByte2HexStr(encryptResult);
System.out.println("加密后1:" + strEncryptResult);
//解密
byte[] byteDecryptResult = parseHexStr2Byte(strEncryptResult);
byte[] decryptResult = decrypt(byteDecryptResult, password); // 普通解密
System.out.println("解密后1:" + new String(decryptResult));
}
结果:
測试代码:EncrptDecrypt.java
java封装AES加密算法的更多相关文章
- PHP android ios相互兼容的AES加密算法
APP项目用户密码传输一直没有用HTTPS,考虑到用户的隐私暂时先用AES对密码加密,以后也可以用于手机端与服务端加密交互. PHP的免费版phpAES项目,手机端解码各种不对. 好不容易找了PHP ...
- 【转】PHP android ios相互兼容的AES加密算法
APP项目用户密码传输一直没有用HTTPS,考虑到用户的隐私暂时先用AES对密码加密,以后也可以用于手机端与服务端加密交互. PHP的免费版phpAES项目,手机端解码各种不对. 好不容易找了PHP ...
- 【java编程】加密算法-对称加密及AES加密算法
转载:https://www.jianshu.com/p/3840b344b27c?utm_campaign=maleskine&utm_content=note&utm_medium ...
- AES 加密算法的原理详解
AES 加密算法的原理详解 本教程摘选自 https://blog.csdn.net/qq_28205153/article/details/55798628 的原理部分. AES简介 高级加密标准( ...
- AES加密算法C++实现
我从网上下载了一套AES加密算法的C++实现,代码如下: (1)aes.h #ifndef SRC_UTILS_AES_H #define SRC_UTILS_AES_H class AES { pu ...
- [Java 实现AES加密解密]
今天同学请教我这个问题,被坑了次…… 实现的功能是2个Java类:一个读取源文件生成加密文件,另一个类读取加密文件来解密. 整个过程其实很简单,java有AES的工具包,设好秘钥,设好输入内容,就得到 ...
- Android AES加密算法及事实上现
昨天老大叫我看看android加密算法.于是网上找了找,找到了AES加密算法.(当然还有MD5,BASE64什么的http://snowolf.iteye.com/blog/379860这篇文章列举了 ...
- JAVA实现AES的加密和解密算法
原文 JAVA实现AES的加密和解密算法 import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import ja ...
- iOS,Android,.NET通用AES加密算法
原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果 ...
随机推荐
- 使用logback实现http请求日志导入mongodb
spring boot自带logback作为其日志新系统,但是在实际工作中,常常需要对日志进行管理或分析,如果只是单纯的将日志导入文本文件,则在查询时操作过于繁琐,如果将其导入mysql等关系型数据库 ...
- 计算某个时间段(2017-10-01 2017-12-01)内svn更新文件的MD5
#!/bin/sh svn up svn log -v -r {$1}:{$2} | grep / | grep -v xxx | sort -f -u | uniq | awk -F 'xxxx' ...
- ABP的一些特性 (Attribute)
大家应该很熟悉Attribute这个东西吧,ABP里面扩展了一些特性,做过滤权限,返回内容等进行控制,在这里小记下,方便后续查看. [DontWrapResult] //ABP默认对返回结果做了封装 ...
- 用 Django2.0 做 简单的BBS(前端用 Bootstrap)
实现目标: 开发首页显示BBS的标题和摘要,点击BBS的标题可跳转到BBS详细页面进行展示. 开发环境及开发工具: Python 3.6.3 Django 2.0 Pycharm 2017.3 实现过 ...
- 易企CMS仿站标签说明
头部标签: 每个页面都必须加的三大标签(将标签放入header.tpl里面,这样只需在每个模板中调用header.tpl即可): <title>{$seotitle}_{$sitename ...
- cannot connect to host的解决办法
作者:朱金灿 来源:http://blog.csdn.net/clever101 下午更新源码,出现下面的错误: 通过ping来测试svn服务器的连接,发现可以连接得通,于是猜测可以服务器的svn服务 ...
- 【VB】api实现窗口最小化
Const WM_SYSCOMMAND = &H112 Const SC_MINIMIZE = &HF020& SendMessage hWnd, WM_SYSCOMMAND, ...
- 【Hexo】本地local4000打不开解决方法
错误:Cannot GET /spadesq.github.io/ (注:spadesq.github.io是原来放hexo文件夹的名字) 由于我后来把hexo文件夹搬迁到别处,但我发现打开本地,地址 ...
- HDU_1398_母函数
Square Coins Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- Typeclassopedia
https://wiki.haskell.org/wikiupload/8/85/TMR-Issue13.pdf By Brent Yorgey, byorgey@gmail.com Original ...