【Java小工匠聊密码学】--消息摘要--SHA算法

简介: 1、什么是SHA算法  安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是联邦信息处理标准(Federal Information Processing Standards,FIPS)所认证的安全散列算法。

1、什么是SHA算法

  安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是联邦信息处理标准(Federal Information Processing Standards,FIPS)所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。

2、SHA算法发展史

2.1 SHA-0

SHA由美国标准与技术研究所(NIST)设计并于1993年发表,该版本称为SHA-0,很快被发现存在安全隐患。

2.2 SHA-1

由于SHA-0中存在的安全隐患,SHA由美国标准与技术研究所(NIST)设计并于1995年发表SHA-1,2005年 SHA-1 算法被破解。
SHA-1在许多安全协议中广为使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被视为是MD5(更早之前被广为使用的散列函数)的后继者。
但SHA-1的安全性如今被密码学家严重质疑。

2.3 SHA-2

NIST在2002年发布了三个额外的SHA变体,这三个函数都将讯息对应到更长的讯息摘要。以它们的摘要长度(以位元计算)加在原名后面来命名:SHA-256,SHA-384和SHA-512。2004年2月加入了一个额外的变种SHA-224",这是为了符合双金钥3DES所需的金钥长度而定义。
至今尚未出现对SHA-2有效的攻击。

3、 SHA 算法对比

image.png

4、SHA 算法实现

4.1 JDK 实现

package lzf.cipher.jdk;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author Java 小工匠
 */
public class JdkShaUtils {

    // SHA 与 SHA-1 算法等价
    public static String sha(byte[] bytes) {
        return shaBase("SHA", bytes);
    }

    // SHA-1 算法
    public static String sha1(byte[] bytes) {
        return shaBase("SHA-1", bytes);
    }

    // SHA-256 算法
    public static String sha256(byte[] bytes) {
        return shaBase("SHA-256", bytes);
    }

    // SHA-384 算法
    public static String sha384(byte[] bytes) {
        return shaBase("SHA-384", bytes);
    }

    // SHA-521 算法
    public static String sha512(byte[] bytes) {
        return shaBase("SHA-512", bytes);
    }

    // SHA基础算法
    public static String shaBase(String sha, byte[] bytes) {
        try {
            // 1、获得SHA摘要算法的 MessageDigest 对象
            MessageDigest digest = MessageDigest.getInstance(sha);
            // 2、使用指定的字节更新摘要
            digest.update(bytes);
            // 3、获得密文
            byte[] rsBytes = digest.digest();
            // 4、把密文转换成十六进制的字符串形式
            return encodeHex(rsBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    // 数据准16进制编码
    public static String encodeHex(final byte[] data) {
        return encodeHex(data, true);
    }

    // 数据转16进制编码
    public static String encodeHex(final byte[] data, final boolean toLowerCase) {
        final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        final char[] toDigits = toLowerCase ? DIGITS_LOWER : DIGITS_UPPER;
        final int l = data.length;
        final char[] out = new char[l << 1];
        // two characters form the hex value.
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
            out[j++] = toDigits[0x0F & data[i]];
        }
        return new String(out);
    }

    public static void main(String[] args) {
        byte[] bytes = "java小工匠".getBytes(Charset.forName("UTF-8"));
        String sha = sha(bytes);
        System.out.println("   sha:" + sha + ",lengh=" + sha.length());
        String sha1 = sha1(bytes);
        System.out.println("  sha1:" + sha1 + ",lengh=" + sha1.length());
        String sha256 = sha256(bytes);
        System.out.println("sha256:" + sha256 + ",lengh=" + sha256.length());
        String sha384 = sha384(bytes);
        System.out.println("sha384:" + sha384 + ",lengh=" + sha384.length());
        String sha512 = sha512(bytes);
        System.out.println("sha512:" + sha512 + ",lengh=" + sha512.length());
    }
}

4.2 CC实现

package lzf.cipher.cc;

import java.nio.charset.Charset;

import org.apache.commons.codec.digest.DigestUtils;

/**
 * @author Java 小工匠
 */
public class CCShaUtils {

    // SHA 与 SHA-1 算法等价
    public static String sha(byte[] bytes) {
        return DigestUtils.sha1Hex(bytes);
    }

    // SHA-1 算法
    public static String sha1(byte[] bytes) {
        return DigestUtils.sha1Hex(bytes);
    }

    // SHA-256 算法
    public static String sha256(byte[] bytes) {
        return DigestUtils.sha256Hex(bytes);
    }

    // SHA-384 算法
    public static String sha384(byte[] bytes) {
        return DigestUtils.sha384Hex(bytes);
    }

    // SHA-521 算法
    public static String sha512(byte[] bytes) {
        return DigestUtils.sha512Hex(bytes);
    }

    public static void main(String[] args) {
        byte[] bytes = "java小工匠".getBytes(Charset.forName("UTF-8"));
        String sha = sha(bytes);
        System.out.println("   sha:" + sha + ",lengh=" + sha.length());
        String sha1 = sha1(bytes);
        System.out.println("  sha1:" + sha1 + ",lengh=" + sha1.length());
        String sha256 = sha256(bytes);
        System.out.println("sha256:" + sha256 + ",lengh=" + sha256.length());
        String sha384 = sha384(bytes);
        System.out.println("sha384:" + sha384 + ",lengh=" + sha384.length());
        String sha512 = sha512(bytes);
        System.out.println("sha512:" + sha512 + ",lengh=" + sha512.length());
    }
}

4.3 BC实现

package lzf.cipher.bc;

import java.nio.charset.Charset;

import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.util.encoders.Hex;

/**
 * @author Java 小工匠
 */
public class BCShaUtils {

    // SHA-1 算法
    public static String sha1(byte[] bytes) {
        Digest digest = new SHA1Digest();
        digest.update(bytes, 0, bytes.length);
        byte[] rsData = new byte[digest.getDigestSize()];
        digest.doFinal(rsData, 0);
        return Hex.toHexString(rsData);

    }

    // SHA-256 算法
    public static String sha256(byte[] bytes) {
        Digest digest = new SHA256Digest();
        digest.update(bytes, 0, bytes.length);
        byte[] rsData = new byte[digest.getDigestSize()];
        digest.doFinal(rsData, 0);
        return Hex.toHexString(rsData);
    }

    // SHA-384 算法
    public static String sha384(byte[] bytes) {
        Digest digest = new SHA384Digest();
        digest.update(bytes, 0, bytes.length);
        byte[] rsData = new byte[digest.getDigestSize()];
        digest.doFinal(rsData, 0);
        return Hex.toHexString(rsData);
    }

    // SHA-521 算法
    public static String sha512(byte[] bytes) {
        Digest digest = new SHA512Digest();
        digest.update(bytes, 0, bytes.length);
        byte[] rsData = new byte[digest.getDigestSize()];
        digest.doFinal(rsData, 0);
        return Hex.toHexString(rsData);
    }

    public static void main(String[] args) {
        byte[] bytes = "java小工匠".getBytes(Charset.forName("UTF-8"));
        String sha1 = sha1(bytes);
        System.out.println("  sha1:" + sha1 + ",lengh=" + sha1.length());
        String sha256 = sha256(bytes);
        System.out.println("sha256:" + sha256 + ",lengh=" + sha256.length());
        String sha384 = sha384(bytes);
        System.out.println("sha384:" + sha384 + ",lengh=" + sha384.length());
        String sha512 = sha512(bytes);
        System.out.println("sha512:" + sha512 + ",lengh=" + sha512.length());
    }
}

如果读完觉得有收获的话,欢迎点赞、关注、加公众号【小工匠技术圈】

个人公众号,欢迎关注,查阅更多精彩历史!

image
相关文章
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
90 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
2月前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
129 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
2月前
|
算法 Java Linux
java制作海报一:java使用Graphics2D 在图片上写字,文字换行算法详解
这篇文章介绍了如何在Java中使用Graphics2D在图片上绘制文字,并实现自动换行的功能。
134 0
|
2月前
|
存储 算法 安全
浅谈SHA算法
浅谈SHA算法
53 0
|
2月前
|
算法 Java 测试技术
数据结构 —— Java自定义代码实现顺序表,包含测试用例以及ArrayList的使用以及相关算法题
文章详细介绍了如何用Java自定义实现一个顺序表类,包括插入、删除、获取数据元素、求数据个数等功能,并对顺序表进行了测试,最后还提及了Java中自带的顺序表实现类ArrayList。
30 0
|
4月前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
66 2
|
8天前
|
算法
基于GA遗传算法的PID控制器参数优化matlab建模与仿真
本项目基于遗传算法(GA)优化PID控制器参数,通过空间状态方程构建控制对象,自定义GA的选择、交叉、变异过程,以提高PID控制性能。与使用通用GA工具箱相比,此方法更灵活、针对性强。MATLAB2022A环境下测试,展示了GA优化前后PID控制效果的显著差异。核心代码实现了遗传算法的迭代优化过程,最终通过适应度函数评估并选择了最优PID参数,显著提升了系统响应速度和稳定性。
|
6天前
|
算法
基于WOA鲸鱼优化的购售电收益与风险评估算法matlab仿真
本研究提出了一种基于鲸鱼优化算法(WOA)的购售电收益与风险评估算法。通过将售电公司购售电收益风险计算公式作为WOA的目标函数,经过迭代优化计算出最优购电策略。实验结果表明,在迭代次数超过10次后,风险价值收益优化值达到1715.1万元的最大值。WOA还确定了中长期市场、现货市场及可再生能源等不同市场的最优购电量,验证了算法的有效性。核心程序使用MATLAB2022a实现,通过多次迭代优化,实现了售电公司收益最大化和风险最小化的目标。
|
3天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于深度学习网络的宝石类型识别算法matlab仿真
本项目利用GoogLeNet深度学习网络进行宝石类型识别,实验包括收集多类宝石图像数据集并按7:1:2比例划分。使用Matlab2022a实现算法,提供含中文注释的完整代码及操作视频。GoogLeNet通过其独特的Inception模块,结合数据增强、学习率调整和正则化等优化手段,有效提升了宝石识别的准确性和效率。
|
9天前
|
算法
基于大爆炸优化算法的PID控制器参数寻优matlab仿真
本研究基于大爆炸优化算法对PID控制器参数进行寻优,并通过Matlab仿真对比优化前后PID控制效果。使用MATLAB2022a实现核心程序,展示了算法迭代过程及最优PID参数的求解。大爆炸优化算法通过模拟宇宙大爆炸和大收缩过程,在搜索空间中迭代寻找全局最优解,特别适用于PID参数优化,提升控制系统性能。