• 哈希算法(一)Java实现常用的哈希算法


    1.简介

    Hash算法: 又称摘要算法。

    • 它的作用:对任意一组输入的数据进行计算,得到一个长度固定的输出算法。
    • 哈希算法的目的:检验元数据是否被篡改。
    • 哈希算法最重要的特点:输入相同的值经过Hash算法一定获得相同的输出,输入不同的值经过Hash算法大概率得到不同的值(有概率哈希碰撞产生相同的值)。

    常见的Hash算法:

    常见Hash算法输出长度(位)
    MD5128bits
    SHA-1160bits
    RipeMD-160256bits
    SHA-256256bits
    SHA-512512bits

    2.MD5算法实现

    1. 通过MessageDigest类的单例模式创建其对象;
    2. 通过对象的update()方法更新原始数据;
    3. 通过对象的digest()方法加密,返回值为字节数组;
    4. 可通过StringBuilder类,将其转换成十六进制的字符串;
    5. MD5加密后的字节数组为16字节,其转换成十六进制的字符串长度为32位。
    public static void main(String[] args) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update("hello".getBytes());
        byte[] resultArray = md5.digest();
        StringBuilder str = new StringBuilder();
        for (byte b : resultArray) {
            str.append(String.format("%02x", b));
        }
        System.out.println(str);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    执行结果:

    5d41402abc4b2a76b9719d911017c592
    
    • 1

    注意:结果中的abcdef可不是字母,而是十六进制!!

    2.SHA-1算法实现

    1. 通过MessageDigest类的单例模式创建其对象;
    2. 通过其对象的update()方法更新原始数据;
    3. 通过其对象的digest()方法加密,其返回值为字节数组
    4. 通过StringBuilder类,将字节数组转换成字符串;
    5. SHA-1算法极爱后的字节数组为20字节,其转换成十六进制的字符串长度为40位。
    String passworf = "hello";
    MessageDigest digest = MessageDigest.getInstance("SHA-1");
    digest.update(passworf.getBytes());
    byte[] digestArray = digest.digest();
    StringBuilder str = new StringBuilder();
    for (byte b : digestArryay) {
        str.append(String.format("%02x", b));
    }
    System.out.println(str);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    执行结果:

    aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
    
    • 1

    小结:

    哈希算法加密中的MD5算法思路和SHA-1算法思路大同小异,两者除了对铭文进行摘要加密还可以进行“加盐”;通过获取随机的数据,将此数据更新至明文中,一起加密;可在一定程度上防御“彩虹表”的攻击。

    3.HmacMD5算法

    在Hmac算法加密时,分成密钥和加密两个部分:

    1. 生成密钥:

      1)通过KeyGenerator类的单例模式创建其对象;

      2)其对象通过generateKey()方法生成Key;

      3)通过Key的getEncoded()方法生成密钥的字节数组;

      4)通过StringBuilder类,将密钥的字节数组转换成十六进制的字符串。

    2. 加密:

      1)通过Mac类的单例模式创建其对象

      2)通过对象的init()方法初始化密钥

      3)通过对象的update()方法更新数据

      4)通过对象的doFinal()方法加密,其返回值为加密的字节数组

      5)通过StringBuilder类,将加密的字节数组转换成十六进制的字符串。

    3. 生成的密钥的字节数为64字节,其加密后的字节数组为16字节。

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
        String password = "hello";
        // 1.生成密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
        SecretKey key = keyGen.generateKey();
        byte[] keyByteArray = key.getEncoded();
        // 2.加密
        Mac mac = Mac.getInstance("HmacMD5");
        mac.init(key);
        mac.update(password.getBytes());
        byte[] resultArray = mac.doFinal();
        StringBuilder str = new StringBuilder();
        for (byte b : resultArray) {
            str.append(String.format("%02x", b));
        }
        System.out.println("加密的内容:" + str);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    执行结果:

    加密的内容:4d84e614aeb1b19e2fe25353306e8012
    
    • 1

    4.RipeMD160算法实现

    此算法的加密基于BouncyCastle提供的第三方库

    1. 注册BouncyCastle提供的注册类对象BouncyCastleProvider;
    2. 通过MessageDigest类的单例模式创建其对象;
    3. 通过其对象的update()方法,更新原始数据;
    4. 通过其对象的digest()方法,进行加密,其返回值为字节数组;
    5. 可通过BigInteger()方法,将字节数组转换成十六进制的字符串;
    6. 加密后字节数组为20字节,其转换成十六进制为40位。
    public static void main(String[] args) throws NoSuchAlgorithmException {
        // 添加第三方库的对象
        Security.addProvider(new BouncyCastleProvider());
        MessageDigest digest = MessageDigest.getInstance("RipeMD160");
        digest.update("hello".getBytes());
        byte[] result = digest.digest();
        String hex = new BigInteger(1, result).toString(16);
        System.out.println("字符串的内容:" + hex);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    执行结果:

    字符串的内容:108f07b8382412612c048d07d13f814118445acd
    
    • 1

    小结:

    哈希算法进行加密,都是摘要加密;加密后不可逆,也就是不可通过解密得到明文。以上就是常见的集中哈希算法。

    整理完毕,完结撒花~





    参考文章:

    1.用Java实现常见的哈希算法,https://blog.csdn.net/m0_58743727/article/details/125963627

    2.Java实现哈希算法,https://blog.csdn.net/qq_55135629/article/details/125921134

  • 相关阅读:
    无序列表和有序列表可以相互嵌套吗?
    【Spring系列】- Bean生命周期底层原理
    Vim实用技巧_0.vim - introduction
    nginx配置proxy_pass之后返回404问题及Nginx host相关变量说明
    如何将base64图片转化为URL格式
    AUTO TECH 2025 广州国际汽车软件与安全技术展览会
    基于ESP8266远程舵机的控制与实现
    LabVIEW创建自定义输入控件、显示控件和自定义类型3
    JavaScript的变量和数据类型介绍、JavaScript的关系运算、JavaScript的逻辑运算
    国产操作系统之凝思磐石安装
  • 原文地址:https://blog.csdn.net/qq_33204709/article/details/127781589