【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】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了