通过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()不是很了解,可以看这篇博客:

使用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发展而来,它们的结构和强度等特性有很多相似之处

因为二者均由MD4导出,SHA-1和MD5彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:
1. 对强行攻击的安全性:最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD5是2^128数量级的操作,而对SHA-1则是2^160数量级的操作。这样,SHA-1对强行攻击有更大的强度。
2. 对密码分析的安全性:由于MD5的设计,易受密码分析的攻击,SHA-1显得不易受这样的攻击。
3. 速度:在相同的硬件上,SHA-1的运行速度比MD5慢。

4. MD5最后生成的摘要信息是16个字节,SHA1是20个字节。

想的太多,做的太少,中间的落差就是烦恼,要么去做,要么别想 少尉【19】

【Java提高】---通过UUID、SHA-1、Base64组合加密的更多相关文章

  1. java提高篇(九)-----实现多重继承

    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...

  2. java提高篇(四)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  3. Java提高篇——Java实现多重继承

    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...

  4. 生成Base58格式的UUID(Hibernate Base64格式的UUID续)

    Base58简介 Base58采用的字符集合为“123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ”,从这不难看出,Base58是纯数 ...

  5. java提高篇(三)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  6. java提高篇(八)-----实现多重继承

    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...

  7. 1.Java 加解密技术系列之 BASE64

    Java 加解密技术系列之 BASE64 序号 背景 正文 总结 序 这段时间,工作中 用到了 Java 的加解密技术,本着学习的态度,打算从这篇文章开始,详细的研究一番 Java 在加解密技术上有什 ...

  8. Java提高篇——对象克隆(复制)

    假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...

  9. Java提高篇(三三)-----Map总结

    在前面LZ详细介绍了HashMap.HashTable.TreeMap的实现方法,从数据结构.实现原理.源码分析三个方面进行阐述,对这个三个类应该有了比较清晰的了解,下面LZ就Map做一个简单的总结. ...

随机推荐

  1. TestNG的使用方法

      本文转载自于:https://blog.csdn.net/qq_24373725/article/category/7432624       TestNG介绍 TestNG是Java中的一个测试 ...

  2. 移动端 去除onclick点击事件出现的背景色框

    这个特效是实现在移动端点击某个地方的时候,比如说按钮或者超链接的时候,系统会默认加上一些灰色的背景和一些高亮的效果.但是有的时候我们并不想要这些效果.并且希望点击的时候实现神不知鬼不觉的感觉,,这个时 ...

  3. P3806 【模板】点分治1

    一道淀粉质的模版题,开始是暴力 #include <bits/stdc++.h> #define up(i,l,r) for(register int i = (l); i <= ( ...

  4. 在idea中,mavne项目使用mybatis-generator-maven-plugin自动生成实体了的时候,在maven插件里面始终不显示

    最近想学习mybatis的知识,自己搭了个简单的ssm框架,想通过插件自动生成实体类,发现想要的插件一直都没显示出来,着实很郁闷: pom.xm中的配置: <!--mybatis-generat ...

  5. [swarthmore cs75] Compiler 6 – Garbage Snake

    课程回顾 Swarthmore学院16年开的编译系统课,总共10次大作业.本随笔记录了相关的课堂笔记以及第9次大作业. 赋值的副作用:循环元组 下面的代码展示了Python3是如何处理循环列表(pri ...

  6. vue图片上传

    之前花了两个月用vue做了一个建筑照片我的webApp,前端就我一人,负责用vue写页面对接接口,后台一个程序员负责写接口,嵌套个安卓ios的壳.搞的是风风火火,过程也是很心累,大多不在技术,在于所谓 ...

  7. 《python语言程序设计》_第5章_循环

    #5.1_引言 程序1: 结果: 程序2: 结果: sum is 45 ##注意整个循环语句都要内缩进循环内部 ##ctrl+c中止一个无限循环运行 程序清单5-1: 结果: #5.2.1_实例研究: ...

  8. react native (2) 嵌入h5页面 设置顶部导航

    嵌入h5页面 1.新建好页面 2. import { WebView } from 'react-native'; 3.<WebView source={{ uri: '要引入的页面路径' }} ...

  9. linux 用tcpdump查看80端口访问有哪些IP

    linux 用tcpdump查看80端口访问有哪些IP: tcpdump -i eth0 -tnn dst port 80 -c 1000|awk -F"." '{print $1 ...

  10. JAVA主流框架---SSM整合

      1.通过监听器的形式引入spring 2.SpringMVC容器和Spring容器间的关系 3.汇通的主旨 让大家熟练掌握SSM调用过程.并且将后台调用彻底掌握. 4.传统项目的搭建的弊端 1.传 ...