【Java提高】---通过UUID、SHA-1、Base64组合加密
通过UUID、SHA-1、Base64组合加密
该篇文章实现的最终效果是:
1)加密是不可逆的。
2)相同字符串加密产生后的字符串都不一样
3)所以要想比较两个字符串是否相等,需要用已经加过密的字符串进行处理后,在与另一个字符串比较。
下面直接代码演示:
加密工具类
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID; import org.apache.commons.codec.binary.Base64; import cn.edu.zju.grs.alufer.exception.InvalidParameterException; /**
* 加密工具类
*/
public class EncryptionUtil { /**
* 先生成一个10位的随机字符串(这个随意)
*/
public static String dealPassword(String password) throws UnsupportedEncodingException {
String salt = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 10);
System.out.println(salt+"---111111");
try { // salt.getBytes("UTF-8"):字符串转成UTF-8的字节数组
return dealPasswordWithSalt(password, salt.getBytes("UTF-8"));
} catch (InvalidParameterException e) {
e.printStackTrace();
}
return null;
} /**
* 通过SHA-1和Base64处理之后,给字符串数据加密在返回字符串
*/
public static String dealPasswordWithSalt(String password, byte[] salt)
throws InvalidParameterException, UnsupportedEncodingException {
if (password == null)
throw new InvalidParameterException("Parameter is null"); // 将两个数组合2为1
byte[] msg = byteCat(password.getBytes("UTF-8"), salt);
String dealedPassword = null; /*
* MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。
* 信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。
*/
MessageDigest md;
try { // 返回实现指定摘要算法的 MessageDigest
// 对象。MessageDigest是java自带加密工具类,通过SHA-1加密,也可以采用MD5
md = MessageDigest.getInstance("SHA-1"); // 使用指定的 byte 数组更新摘要。
md.update(msg); // 通过执行诸如填充之类的最终操作完成哈希计算。digest 方法只能被调用一次。在调用 digest
// 之后,MessageDigest 对象被重新设置成其初始状态。
byte[] dig = md.digest(); // 在合2为1
byte[] passb = byteCat(dig, salt); // 最后通过BASE64算法转换二进 制数据为ASCII字符串格式。
dealedPassword = new String(Base64.encodeBase64(passb));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return dealedPassword;
} /**
* 这个方法的目的是将两个数组合成一个数组
*/
private static byte[] byteCat(byte[] l, byte[] r) {
byte[] b = new byte[l.length + r.length];
System.arraycopy(l, 0, b, 0, l.length);
System.arraycopy(r, 0, b, l.length, r.length);
return b;
} /**
* 通过上面生成的字符串来进行解密,其最终目的就是获得上面随机生成的UUID
* 这样只要你password一致,UUID一致,那dealPasswordWithSalt方法产生的加密字符串就会一致
*/
public static byte[] getSalt(String dealedPassword) throws InvalidParameterException { /*
* 解码:这里获得的是上面passb数组,因为SHA-1是固定20个字节,所以从20位置开始截取,MD516个字节。
*/
byte[] decoded = Base64.decodeBase64(dealedPassword);
byte[][] bs = null;
bs = byteSplit(decoded, 20);
byte[] salt = bs[1];
System.out.println(new String(salt)+"---222222");
return salt;
} /**
* 将数组1分为2,其实就是获得上面uuid所产生的数组
* 第一个数组是上面dig数组,第二个是salt数组
*/
private static byte[][] byteSplit(byte[] src, int n) {
byte[] l, r;
if (src == null || src.length <= n) {
l = src;
r = new byte[0];
} else {
l = new byte[n];
r = new byte[src.length - n];
System.arraycopy(src, 0, l, 0, n);
System.arraycopy(src, n, r, 0, r.length);
}
byte[][] lr = { l, r };
return lr;
} }
测试类
import java.io.UnsupportedEncodingException; import cn.edu.zju.grs.alufer.exception.InvalidParameterException; public class Test { public static void main(String[] args) {
try {
try { //模拟获得用户注册的密码
String password="zhang123456"; //通过加密获得的密码,存放到数据库
String plusPassword = EncryptionUtil.dealPassword(password);
System.out.println("加密后:"+plusPassword); //模拟用户登录
String loginpassword="zhang123456";
String LessPassword= EncryptionUtil.dealPasswordWithSalt(loginpassword,EncryptionUtil.getSalt(plusPassword));
System.out.println("在加密:"+LessPassword); System.out.println(plusPassword.equals(LessPassword));
} catch (InvalidParameterException e) {
e.printStackTrace();
} } catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* 总结:
* 1:通过UUID有个最大的好处就是它会产生随机数,所以你同样的两个字符串它的加密后结果是不一样的,
* 你要解密,那你首先要做的是要先得到那个UUID字符串,在进行加密,才会之前的加密字符串一致
*
*/
}
看后台打印:
看上面的例子,如果你对System.arraycopy()不是很了解,可以看这篇博客:
它对里面的参数做了详细讲解。
总结下
加密过程:
1)将用户前段传入的password传入加密方法中。
2)加密方法先通过UUID随机生成字符串,可以理解为salt。
3)将password和salt都转为byte[],在通过system.arrayCopy方法变成一个byte[]
4)将上面的byte[]进行SHA-1加密,之后在于salt组成的byte[],组成一个新的byte[](也就是说这个salt在加密过程中使用了两次,第二次是为解密用的)
5)在通过Base64进行加密。
解密过程:
解密过程的关键就是要获得加密过程的salt。
1)通过Base64.decodeBase64将数据的密码转为byte数组。
2)截取byte数组20个字节后的字节(因为SHA-1是固定20个字节,那么剩下的就是盐了)
3) 只要获得盐,那就把用户登录的密码和盐再加密一次,和数据库的密码一样就代码验证通过。
MD5 和 SHA-1的区别
最后说下:MD5 和 SHA-1 的一些区别:
由于MD5与SHA-1均是从MD4发展而来,它们的结构和强度等特性有很多相似之处
4. MD5最后生成的摘要信息是16个字节,SHA1是20个字节。
想的太多,做的太少,中间的落差就是烦恼,要么去做,要么别想 少尉【19】
【Java提高】---通过UUID、SHA-1、Base64组合加密的更多相关文章
- java提高篇(九)-----实现多重继承
多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...
- java提高篇(四)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- Java提高篇——Java实现多重继承
多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...
- 生成Base58格式的UUID(Hibernate Base64格式的UUID续)
Base58简介 Base58采用的字符集合为“123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ”,从这不难看出,Base58是纯数 ...
- java提高篇(三)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- java提高篇(八)-----实现多重继承
多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...
- 1.Java 加解密技术系列之 BASE64
Java 加解密技术系列之 BASE64 序号 背景 正文 总结 序 这段时间,工作中 用到了 Java 的加解密技术,本着学习的态度,打算从这篇文章开始,详细的研究一番 Java 在加解密技术上有什 ...
- Java提高篇——对象克隆(复制)
假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...
- Java提高篇(三三)-----Map总结
在前面LZ详细介绍了HashMap.HashTable.TreeMap的实现方法,从数据结构.实现原理.源码分析三个方面进行阐述,对这个三个类应该有了比较清晰的了解,下面LZ就Map做一个简单的总结. ...
随机推荐
- 阿里oss图片上传
<script type="text/javascript" src="../../static/js/manage/oss_uploader.js"&g ...
- RQNOJ PID51 / 乒乓球 ☆
因为是多行输入,所以用了getchar()进行输入,题目没有说明数据范围,所以开始的时候因为数组开的不够大,WA90了一次,我之前开了10000的长度,之后开100000的长度跑过了 一个基本的模拟, ...
- python3 tkinter添加图片和文本
在前面一篇文章基础上,使用tkinter添加图片和文本.在开始之前,我们需要安装Pillow图片库. 一.Pillow的安装 1.方法一:需要下载exe文件,根据下面图片下载和安装 下载完 ...
- C# Winform Soket 网络编程 多个客户端连接服务器并返回客户端操作请求
2017.8.2 服务器: #region 参数与集合 /// <summary> /// 客户端IP /// </summary> string clientIP; /// ...
- Java————迷宫问题
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线. package algorithm_java; import java. ...
- 2019.03.25 bzoj4568: [Scoi2016]幸运数字(倍增+线性基)
传送门 题意:给你一棵带点权的树,多次询问路径的最大异或和. 思路: 线性基上树?? 倍增维护一下就完了. 时间复杂度O(nlog3n)O(nlog^3n)O(nlog3n) 代码: #include ...
- 2019.03.25 bzoj4567: [Scoi2016]背单词(trie+贪心)
传送门 题意: 给你n个字符串,不同的排列有不同的代价,代价按照如下方式计算(字符串s的位置为x): 1.排在s后面的字符串有s的后缀,则代价为n^2: 2.排在s前面的字符串有s的后缀,且没有排在s ...
- MySQL平时记录笔记
零,mysql的安装 http://blog.csdn.net/mhmyqn/article/details/17043921 https://www.cnblogs.com/wangjunyan/p ...
- JAVA 8 主要新特性 ----------------(七)新时间日期 API -----LocalDateTime
一.LocalDateTime简介 二.实战讲解 LocalDateTime localDateMax = LocalDateTime.MAX; System.out.println("lo ...
- tomcat配置层了解一下 idea打包 java打包部署
Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件是配置的核心文件. 如果想修改Tomcat服务器的启动端口,则可以在server.xml配置文件中的Connector节点 ...