在实际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加密算法的更多相关文章

  1. PHP android ios相互兼容的AES加密算法

    APP项目用户密码传输一直没有用HTTPS,考虑到用户的隐私暂时先用AES对密码加密,以后也可以用于手机端与服务端加密交互. PHP的免费版phpAES项目,手机端解码各种不对. 好不容易找了PHP ...

  2. 【转】PHP android ios相互兼容的AES加密算法

    APP项目用户密码传输一直没有用HTTPS,考虑到用户的隐私暂时先用AES对密码加密,以后也可以用于手机端与服务端加密交互. PHP的免费版phpAES项目,手机端解码各种不对. 好不容易找了PHP ...

  3. 【java编程】加密算法-对称加密及AES加密算法

    转载:https://www.jianshu.com/p/3840b344b27c?utm_campaign=maleskine&utm_content=note&utm_medium ...

  4. AES 加密算法的原理详解

    AES 加密算法的原理详解 本教程摘选自 https://blog.csdn.net/qq_28205153/article/details/55798628 的原理部分. AES简介 高级加密标准( ...

  5. AES加密算法C++实现

    我从网上下载了一套AES加密算法的C++实现,代码如下: (1)aes.h #ifndef SRC_UTILS_AES_H #define SRC_UTILS_AES_H class AES { pu ...

  6. [Java 实现AES加密解密]

    今天同学请教我这个问题,被坑了次…… 实现的功能是2个Java类:一个读取源文件生成加密文件,另一个类读取加密文件来解密. 整个过程其实很简单,java有AES的工具包,设好秘钥,设好输入内容,就得到 ...

  7. Android AES加密算法及事实上现

    昨天老大叫我看看android加密算法.于是网上找了找,找到了AES加密算法.(当然还有MD5,BASE64什么的http://snowolf.iteye.com/blog/379860这篇文章列举了 ...

  8. JAVA实现AES的加密和解密算法

    原文 JAVA实现AES的加密和解密算法 import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import ja ...

  9. iOS,Android,.NET通用AES加密算法

    原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果 ...

随机推荐

  1. POJ 3635 优先队列BFS

    (感谢lyd学长的幻灯片) 注意vis数组的应用 在vis[i][j]中 i表示到了第i个点 j表示还剩j升油 vis[i][j]表示最小话费. 这样只需搜到话费比它少的更新入堆就OK了 //By: ...

  2. ACM_来自不给标题的菜鸟出题组(巴什博弈+素数判定)

    来自不给标题的菜鸟出题组 Time Limit: 2000/1000ms (Java/Others) Problem Description: 大B和小b合作出一道程序设计月赛的题,他们的想法是给定一 ...

  3. C语言笔记(一)

    笑话一枚:程序员 A:“哥们儿,最近手头紧,借点钱?”程序员 B:“成啊,要多少?”程序员 A:“一千行不?”程序员 B:“咱俩谁跟谁!给你凑个整,1024,拿去吧.” =============== ...

  4. 《Linux程序设计》笔记(二)shell程序设计

    1. 进程树形显示 ps -e f 2. 重定向 > 覆盖文件 >> 附加至文件 1> 标准输出 2> 标准错误输出 0 代表一个程序的标准输入 3. 程序可以在当前目录 ...

  5. 安卓代码迁移:Make.exe: *** [libs/armabi-v7a/gdbserver] Error 1

    解决办法1:安装ndk和eclipse修改为x86操作系统 解决办法2:降低更换NDK版本

  6. dapper.net 存储过程

    var param = new DynamicParameters(); param.Add(); param.Add(); param.Add(, DbType.Int32, ParameterDi ...

  7. JSP_内置对象_session

    session表示客户端与服务器的一次会话. Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间. 从上述定义中可以看到,s ...

  8. python tips:类的专有属性

    实例通常能够调用类的属性,但是有些属性是类专有的,实例无法调用. 实例调用方法时查找属性时,首先在自己的__dict__中找,找不到去类中找,在类中能够找到的属性都位于dir(cls)中,如果类的某些 ...

  9. day37-1 面向对象高阶

    目录 面向对象高阶 isinstance issubclass 反射(自省) 模块的使用 放在类的使用 call 面向对象高阶 isinstance 判断是否为实例化对象,以后可以用来取代type 和 ...

  10. MySQL+Keepalived实现主主高可用方案

    Mysql主主高可用方案 master配置 [root@master ~]# yum -y install keepalived [root@master ~]# vim /etc/keepalive ...