关于SHA算法原理与常用实现方式

 更新时间:2022年08月18日 11:35:42   作者:zhangSir134  
这篇文章主要介绍了关于SHA算法原理与常用实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

看本文前,最好先看看之前的这一篇关于MD5算法的介绍。

MD5算法原理与常用实现

定义

SHA算法(Secure Hash Algorithm),又叫安全散列算法。

SHA算法是基于MD4算法的基础上,演变而来。

但SHA算法出生好,是美国国家安全局设计的。

SHA算法,是一个系列家族,包括SHA-1,SHA-2(SHA-224、SHA-256、SHA-384、SHA-512),括号中的四个通常被统称为SHA-2。

JDK中对SHA-1、SHA-256、SHA-384、SHA-512都有实现。

  • SHA-1的最终密码长度是160位。
  • SHA-256的最终密码长度是256位。
  • SHA-384的最终密码长度是384位。
  • SHA-512的最终密码长度是512位。

SHA算法,实际上也是一种消息摘要算法,这个和MD算法是类似的。

本文主要介绍SHA-256算法。

任意长度的消息文件,通过SHA-256算法加密,最终得到的密文都是256位(32字节),通常用一个长度为64的十六进制字符串来表示。

效果上,SHA算法,与MD5算法都差不多,主要特点都是不可逆。

MD5和SHA-1的碰撞问题

碰撞问题,就是指对于一个算法,由明文生成的密文,并不是唯一的,甚至可以人为的通过构造新的明文去得到指定的密文。

对于能出现这种情况的算法,我们就说这个算法是有碰撞问题的,简单理解就是两个不同的明文,通过算法加密,却得到了同样的密文。

目前为止,MD5算法和SHA-1算法,都被证实了存在碰撞问题。

所以在安全性特别高的场景下,都不会用MD5算法和SHA-1算法,至少都用SHA-256算法了。

常见应用场景

1、类似MD5的应用场景

MD5的应用场景,SHA算法基本也都可以使用。

2、比特币

比特币中,挖矿算法其实就是SHA-256算法,矿工们根据不断修改随机数,不断的进行SHA-256运算,最终算的快的挖到矿。

3、https签名算法会用到

打开浏览器,以谷歌为例,查看任意一个整数的详情:

签名算法就是:带 RSA 加密的 SHA-256,如下图:

SHA-256算法原理

SHA家族的基本算法思想,都和MD5一样,先定义常量,然后循环计算,最后组装,不同的就是循环里面的计算方式。

1、填补信息

类似MD5

2、拿到初始值

MD5中有4个初始值,而SHA-256中,有8个。

h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19

3、真正的计算

计算分为多次循环,每次循环,都是用ABCD和原文在第一步填补完的信息,进行计算,最终得到新的ABCD。最后将最后一次ABCD拼成字符串,就是最终的密文。

  • 循环先分为主循环,每个主循环中又套有子循环。
  • 主循环次数 = 原文长度/512。
  • 子循环次数 = 64次。

我们看看单次子循环都做了什么:

下面是单次子循环真正的计算逻辑(这段实现摘自网友):

java实现和使用

其实看过上一篇MD5介绍的,就会发现,其实SHA的java实现,和MD5的java实现,几乎一模一样。

唯一的不同,就是MessageDigest.getInstance(“SHA”);这个方法中:

  • SHA-1算法的入参是SHA
  • SHA-256算法的入参是SHA-256
  • SHA-384算法的入参是SHA-384
  • SHA-512算法的入参是SHA-512

MD5的入参是MD5

public class SHA1Util {
    public static void main(String[] args) throws IOException {
        System.out.println(encodeString("123"));
    }
    public static String encodeString(String plainText) throws UnsupportedEncodingException {
        return encodeBytes(plainText.getBytes("UTF-8"));
    }
    public static String encodeBytes(byte[] bytes) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(bytes);
            byte b[] = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }
            return buf.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

相关文章

  • SpringBoot如何使用TraceId日志链路追踪

    SpringBoot如何使用TraceId日志链路追踪

    文章介绍了如何使用TraceId进行日志链路追踪,通过在日志中添加TraceId关键字,可以将同一次业务调用链上的日志串起来,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • 使用redisTemplate的scan方式删除批量key问题

    使用redisTemplate的scan方式删除批量key问题

    这篇文章主要介绍了使用redisTemplate的scan方式删除批量key问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • IDEA配置JRebel实现热部署的方法

    IDEA配置JRebel实现热部署的方法

    这篇文章主要介绍了IDEA配置JRebel实现热部署的方法,本文给大家介绍的非常想详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • java实现网上购物车程序

    java实现网上购物车程序

    这篇文章主要介绍了java实现网上购物车程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • MyBatis实现批量插入方法实例

    MyBatis实现批量插入方法实例

    最近在公司项目开发中遇到批量数据插入或者更新,下面这篇文章主要给大家介绍了关于MyBatis实现批量插入的相关资料,需要的朋友可以参考下
    2022-10-10
  • 面试官问如何启动Java 线程

    面试官问如何启动Java 线程

    这篇文章主要介绍了面试官问如何启动Java 线程,Java 的线程创建和启动非常简单,但如果问一个线程是怎么启动起来的往往并不清楚,甚至不知道为什么启动时是调用start(),而不是调用run()方法呢?下面我们就一起进入文章学习这个问题吧
    2021-12-12
  • spring本地事务失效的原因分析

    spring本地事务失效的原因分析

    这篇文章给大家介绍了spring本地事务失效的情况原因分析,给大家罗列了五种原因分析,通过代码示例介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2023-10-10
  • Java 连接Access数据库的两种方式

    Java 连接Access数据库的两种方式

    这篇文章主要介绍了Java 连接Access数据库的两种方式,本文着重讲解使用JDBC连接操作Access数据库,需要的朋友可以参考下
    2015-06-06
  • SpringSecurity如何实现配置单个HttpSecurity

    SpringSecurity如何实现配置单个HttpSecurity

    这篇文章主要介绍了SpringSecurity如何实现配置单个HttpSecurity,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • 使用SpringBoot注解方式处理事务回滚实现

    使用SpringBoot注解方式处理事务回滚实现

    这篇文章主要介绍了使用SpringBoot注解方式处理事务回滚实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08

最新评论