项目中又遇到了加密问题,又去翻了半天,然后做测试,干脆就把常用的两类小结一下.

1.第一种所谓的MD5加密

 其实也不算加密,只是基于Hash算法的不可逆编码而已,等于说,一旦经过MD5处理,是不可能从编码后的字符串反推回去的.

 MD5的方法是基于散列的。本身信息不全。理论上是不能还原成唯一字符串的。

 网上所谓的解密,也只是拥有一个足够大的字典映射,将编码前的源字符和编码后的目标字符关联起来而已,大多数常见的还行,复杂点的估计就会话费很长时间,有兴趣的可以试试.

 

 至于MD5的用法,在初次录入的时候,也就做一次编码,而后存储,没什么可说的.主要是验证一致性,如登录中的密码,普遍做法就是将新获取的密码编码,在用编码之后的和数据库中的比较,判断是否一致.

 理论上来讲,对于这个密码,除了使用的人,其他人是不知道的,包括管理员.

 一般的系统这种方案也就够用了.或者利用MD5多次编码(加密),次数自己控制即可,也能增加点安全性.

2.第二种就是AES加密/解密

 AES 是一种对称加密算法,加密过程中要使用密钥这个东西. 有兴趣的可以去仔细了解一下: http://www.mamicode.com/info-detail-514466.html

 就是说,我有个密码:mima001,要使用AES加密,此时我就需要提供一个 密钥(key) :thisKey,然后使用AES算法加密,得到一个结果result,存入数据库;

 然后,解密的时候,我们从数据库中拿到这个result,然后同时也要获得上面加密的时候用到的密钥:thisKey,然后使用AES算法解密;

 在这个过程中,如果有密钥,则整个过程是可逆的,并且密钥只有一个,可逆相对来说也就是对称的,加密前和解密后的东西,没有什么差异.

另外,补充一点啊,就是加密解密基础问题:字节数组和(16进制)字符串的相互转换

在加密时,一般加密算法和hash算法,它们操作的都是字节数组,对字节数组按照加密算法进行各种变换,运算,得到的结果也是字节数组。而我们一般是要求对字符串进行加密,所以就涉及到字符串String到 byte[] 的转换,这个很简单。同时在解密时,也涉及到字节数组byte[] 到 String 的转换。另外在对用户的密码进行hash加密之后,最终是要保存在数据库中,所以加密得到 byte[] 也要转换到 String.

想了解详细一点的朋友可以去: http://www.cnblogs.com/digdeep/p/4627813.html 看看.

下面是工具类:提供了加密方法,解密方法,还有讲加密结果转换为常见的字符串转换方法.

 import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; /**
* @see: PasswordUtil
* @author: lnexin@aliyun.com
* @date: 2017-04-29 10:12
*/
public class PasswordUtil {
/**
* 使用:
* 直接使用即可,至于具体参数,看下面方法的说明即可;
* 1. PasswordUtil.MD5Encode(); MD5不可逆简单加密:散列函数-基于HASH算法的编码
* 2. PasswordUtil.AESEncrypt(); AES加密
* 3. PasswordUtil.AESDecrypt(); AES解密
* 4. PasswordUtil.parseByte2HexStr(); 二进制到16进制
* 5. PasswordUtil.parseHexStr2Byte(); 16进制到2进制
*/ // 16进制的字符数组
private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; /**
* @param source 原字符串
* @param encoding 指定编码类型
* @param uppercase 是否转为大写字符串
*/
public static String MD5Encode(String source, String encoding, boolean uppercase) {
String result = null;
try {
result = source;
// 获得MD5摘要对象
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
// 使用指定的字节数组更新摘要信息
messageDigest.update(result.getBytes(encoding));
// messageDigest.digest()获得16位长度
// result = parseByte2HexStr(messageDigest.digest());
result = byteArrayToHexString(messageDigest.digest()); } catch (Exception e) {
e.printStackTrace();
}
return uppercase ? result.toUpperCase() : result;
} /**
* AES 加密
*
* @param content 需要加密的内容
* @param aesKey 加密密钥
* @return
*/
public static byte[] AESEncrypt(String content, String aesKey) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(aesKey.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 aesKey 解密密钥 秘miyao
* @return
*/
public static byte[] AESDecrypt(byte[] content, String aesKey) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(aesKey.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;
} /**
* 将二进制转换成16进制
*/
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进制转换为二进制
*/
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;
}

     //byte转16进制
private static String byteArrayToHexString(byte[] bytes) {
StringBuilder stringBuilder = new StringBuilder();
for (byte tem : bytes) {
stringBuilder.append(byteToHexString(tem));
}
return stringBuilder.toString();
}
//16进制转byte[]
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n = 256 + n;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
} }

使用说明:

随便写个测试类:截图直观一点,控制台输出在图右下角,测试具体代码在文末.

 public class PasswordTest {

     @Test
public void MD5Test() throws Exception {
String encode = PasswordUtil.MD5Encode("admin", "UTF8", true);
System.out.println();
System.out.println("MD5算法:"+encode);
} @Test
public void aesTest() throws Exception {
String content = "admin";
String aesKey = "thisiskey"; byte[] encrypt = PasswordUtil.AESEncrypt(content, aesKey);//加密
System.out.println("AES加密后-byte[]:"+encrypt); String strHex = PasswordUtil.parseByte2HexStr(encrypt);
System.out.println("转换后的十六进制:"+strHex); byte[] decrypt = PasswordUtil.AESDecrypt(PasswordUtil.parseHexStr2Byte(strHex), aesKey);//解密
System.out.println("AES解密后-byte[]"+decrypt);
System.out.println("AES解密转换后:"+new String(decrypt));
} }

使用工具类的时候,要传入什么参数,主要方法上面的注释即可;

Java 关于密码处理的工具类[MD5编码][AES加密/解密]的更多相关文章

  1. C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现[转载]

    原文:http://outofmemory.cn/code-snippet/35524/AES-with-javascript-java-csharp-python-or-php c#里面的AES加密 ...

  2. C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  3. Java AES加密解密工具 -- GUI 、在线传输文件

    原理 对于任意长度的明文,AES首先对其进行分组,每组的长度为128位.分组之后将分别对每个128位的明文分组进行加密. 对于每个128位长度的明文分组的加密过程如下:     (1)将128位AES ...

  4. Java操作文件夹的工具类

    Java操作文件夹的工具类 import java.io.File; public class DeleteDirectory { /** * 删除单个文件 * @param fileName 要删除 ...

  5. Java汉字转成汉语拼音工具类

    Java汉字转成汉语拼音工具类,需要用到pinyin4j.jar包. import net.sourceforge.pinyin4j.PinyinHelper; import net.sourcefo ...

  6. java中excel导入\导出工具类

    1.导入工具 package com.linrain.jcs.test; import jxl.Cell; import jxl.Sheet; import jxl.Workbook; import ...

  7. java中定义一个CloneUtil 工具类

    其实所有的java对象都可以具备克隆能力,只是因为在基础类Object中被设定成了一个保留方法(protected),要想真正拥有克隆的能力, 就需要实现Cloneable接口,重写clone方法.通 ...

  8. java代码行数统计工具类

    package com.syl.demo.test; import java.io.*; /** * java代码行数统计工具类 * Created by 孙义朗 on 2017/11/17 0017 ...

  9. Java加载Properties配置文件工具类

    Java加载Properties配置文件工具类 import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; ...

随机推荐

  1. java包名命名规范[【转】

    indi : 个体项目,指个人发起,但非自己独自完成的项目,可公开或私有项目,copyright主要属于发起者. 包名为“indi.发起者名.项目名.模块名.……”. pers : 个人项目,指个人发 ...

  2. 多线程处理N维度topk问题demo--[c++]

    问题 -对多维度特征进行topk排序,使用c++ 优先队列模拟最大堆. /* ---------------------------------- Version : ?? File Name : d ...

  3. 构建自己的 Smart Life 私有云(一)-> 破解涂鸦智能插座

    博客搬迁至https://blog.wangjiegulu.com RSS订阅:https://blog.wangjiegulu.com/feed.xml 原文链接:https://blog.wang ...

  4. 带你Python入门,踏进人工智能领域

    1.Python能做什么? 不知大家 没有看<中国好声音>呢?有位选择就是利用AI改编了一首周杰伦的歌<止战之殇>. Python适合做人工智能AI吗? 很明确的告诉你,可以! ...

  5. Myeclipse安装、配置、测试

    Myeclipse安装.配置.测试(win7_64bit) 目录 1.概述 2.本文用到的工具 3.安装与激活 4.JavaSE开发测试(确保JDK已正确安装) 5.JavaEE开发测试(确保服务器和 ...

  6. 如何关闭windows server2012 80端口

    Windows Server禁用本地端口的两种方法 这篇文章主要介绍了Windows Server 2008 禁用本地端口的两种方法,本文讲解了通过Windows防火墙禁用端口.通过IP安全策略禁用端 ...

  7. spring MVC配置详解(转)

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...

  8. windows系统下修改键盘按键的映射

    待解决的问题: 在windows系统下,在某些情况下,我们感觉键盘的按键位置不是特别方便,因此想重新映射它. 比如:要实现如下重新映射(我就有这样的需求),怎么办? Esc键 修改为 CapsLock ...

  9. Angular4中路由Router类的跳转navigate

    最近一直在学习angular4,它确实比以前有了很大的变化和改进,好多地方也不是那么容易就能理解,好在官方的文档和例子是中文,对英文不太好的还是有很大帮助去学习. 官方地址:https://angul ...

  10. tensorflow简单记录summary方法

    虽然tf官方希望用户把 train , val 程序分开写,但实际开发中,明显写在一起比较简单舒服,但在保存数据到 summary 时, val 部分和 train 部分不太一样,会有一些问题,下面讨 ...