0


常见哈希算法总结

哈希算法概述

哈希算法又称摘要算法,它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算法的目的:为了验证原始数据是否被篡改。

哈希算法的特点就是:

1.相同的输入一定得到相同的输出;

2.不同的输入大概率得到不同的输出。

常见的哈希算法:

算法输出长度(位)输出长度(字节)MD5128bit16bytesSHA-1160bit20bytesRipeMD-160160bit20bytesSHA-256256bit32bytesSHA-512512bit64bytes
Java标准库提供了常用的哈希算法,并且有一套统一的接口。以MD5算法为例,看看如何对输入计算哈希:

MD5算法

    public static void main(String[] args) throws IOException {

        try {            
           //获取一个MessageDigest对象:
            MessageDigest digest = MessageDigest.getInstance("MD5");
            //把要加密的内容转换成字节数据
            byte[] simpledata = "hnczjtyrbl".getBytes();
            System.out.println("原始数据:"+Arrays.toString(simpledata));
            digest.update(simpledata);
            //获得加密后的数据:
            byte[] result = digest.digest();
            System.out.println("加密后的数据:"+Arrays.toString(result));
            //转换成十六进制的字符串
            StringBuilder sb = new StringBuilder();
            for(byte b:result) {
                sb.append(String.format("%x", b));
            }
            
            System.out.println("转换成16进制字符串:"+sb);
            System.out.println("长度:"+sb.length());
            } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

MD5算法先获得一个MessageDigest对象,然后用update()方法传入要加密内容的字节数组。然后通过digest()方法获得最终加密的结果。

SHA-1算法:

SHA-1算法和MD5算法用法类似,不同的一点就是MD5加密的结果是一个长度为16的字节数组,而SHA-1加密的结果是一个长度为20的字节数组。

public static void main(String[] args) throws IOException {

        try {// 要加密的内容
            String password = "hdljdylzsx";
            // 创建一个MessageDigest对象:
            MessageDigest digest1 = MessageDigest.getInstance("SHA-1");
            // 更新要加密的数据
            digest1.update(password.getBytes());
            byte[] resultArray1 = digest1.digest();
            System.out.println("原始数据:" + Arrays.toString(password.getBytes()));
            // 加密后的结果
            System.out.println("加密后的结果:" + Arrays.toString(resultArray1));
            System.out.println("长度:" + resultArray1.length);
            StringBuilder sb = new StringBuilder();
            for (byte b : resultArray1) {
                sb.append(String.format("%x", b));
            }
            System.out.println("转换成16进制字符串:" + sb);
            System.out.println("长度:" + sb.length());

        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

哈希算法的用途

校验下载文件

因为相同的输入永远会的到相同的输出,因此,如果输入被修改了,得到的输出就会不同。我们在网站上下载软件的时候,经常会看到下载页显示MD5哈希值:

不存储用户的原始口令,那么如何对用户进行认证?方法是存储用户口令的哈希,例如,MD5。在用户输入原始口令后,系统计算用户输入的原始口令的MD5并与数据库存储的MD5对比,如果一致,说明口令正确,否则,口令错误。

如何判断下载到本地的软件是原始的、未经篡改的文件?我们只需要自己计算一下本地文件的哈希值,再与官网公开的哈希值对比,如果相同,说明文件下载正确,否则,说明文件已被篡改。

存储用户密码

哈希算法的另一个重要用途是存储用户口令。如果直接将用户的原始口令存放到数据库中,会产生极大的安全风险:
1.数据库管理员能够看到用户明文口令;
2.数据库数据一旦泄漏,黑客即可获取用户明文口令。

使用哈希口令时,还要注意防止彩虹表攻击。什么是彩虹表呢?上面讲到了,如果只拿到MD5,从MD5反推明文口令,只能使用暴力穷举的方法。然而黑客并不笨,暴力穷举会消耗大量的算力和时间。但是,如果有一个预先计算好的常用口令和它们的MD5的对照表,这个表就是彩虹表。如果用户使用了常用口令,黑客从MD5一下就能反查到原始口令:

当然,我们也可以采取特殊措施来抵御彩虹表攻击:对每个口令额外添加随机数,这个方法称之为“加盐”。这样即使数据库泄露,黑客也不能获得用户明文。

Hmac MD5算法

public static void main(String[] args) {
        String password = "yyzsbjr";
        try {
            // 生成秘钥
            // 秘钥生成器keyGenerator
            KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
            //生成秘钥key
            SecretKey key = keyGen.generateKey();
            byte[] keyByteArray = key.getEncoded();
            System.out.println("秘钥长度" + keyByteArray.length);
            StringBuilder sb = new StringBuilder();
            for (byte b : keyByteArray) {
                sb.append(String.format("%02x", b));
            }
            System.out.println(sb);

            System.out.println(sb.length());
            Mac mac = Mac.getInstance("HmacMD5");
            mac.init(key);
            mac.update(password.getBytes());
            byte[] resultByteArray = mac.doFinal();
            System.out.println("加密结果:" + resultByteArray.length + "字节");
            StringBuilder resultStr = new StringBuilder();
            for (byte b : resultByteArray) {
                resultStr.append(String.format("%02x", b));

            }
            System.out.println("加密长度" + resultStr.length());
            System.out.println("加密内容:" + resultStr);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

和MD5相比,使用HmacMD5的步骤是:
1.通过名称HmacMD5获取KeyGenerator实例;
2.通过KeyGenerator创建一个SecretKey实例;
3.通过名称HmacMD5获取Mac实例;
4.用SecretKey初始化Mac实例;
5.对Mac实例反复调用update(byte[])输入数据;
6.调用Mac实例的doFinal()获取最终的哈希值。得到加密后的结果。


本文转载自: https://blog.csdn.net/m0_59340907/article/details/125918939
版权归原作者 磨剑斩秋招 所有, 如有侵权,请联系我们删除。

“常见哈希算法总结”的评论:

还没有评论