【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
相关文章
|
16天前
|
算法 安全 Java
java代码 实现AES_CMAC 算法测试
该代码实现了一个AES-CMAC算法的简单测试,使用Bouncy Castle作为安全提供者。静态变量K定义了固定密钥。`Aes_Cmac`函数接受密钥和消息,返回AES-CMAC生成的MAC值。在`main`方法中,程序对给定的消息进行AES-CMAC加密,然后模拟接收ECU的加密结果并进行比较。如果两者匹配,输出&quot;验证成功&quot;,否则输出&quot;验证失败&quot;。辅助方法包括将字节转为16进制字符串和将16进制字符串转为字节。
|
22天前
|
搜索推荐 Java
Java排序算法
Java排序算法
18 0
|
22天前
|
搜索推荐 Java
Java基础(快速排序算法)
Java基础(快速排序算法)
23 4
|
25天前
|
存储 算法 JavaScript
Java入门高频考查算法逻辑基础知识3-编程篇(超详细18题1.8万字参考编程实现)
解决这类问题时,建议采取下面的步骤: 理解数学原理:确保你懂得基本的数学公式和法则,这对于制定解决方案至关重要。 优化算法:了解时间复杂度和空间复杂度,并寻找优化的机会。特别注意避免不必要的重复计算。 代码实践:多编写实践代码,并确保你的代码是高效、清晰且稳健的。 错误检查和测试:要为你的代码编写测试案例,测试标准的、边缘情况以及异常输入。 进行复杂问题简化:面对复杂的问题时,先尝试简化问题,然后逐步分析和解决。 沟通和解释:在编写代码的时候清晰地沟通你的思路,不仅要写出正确的代码,还要能向面试官解释你的
33 0
|
28天前
|
XML 存储 算法
Java数据结构与算法-java数据结构与算法(五)
Java数据结构与算法-java数据结构与算法
48 0
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真
|
1月前
|
算法
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
23 2
|
1月前
|
算法
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
39 1
|
4天前
|
机器学习/深度学习 人工智能 算法
基于DCT和扩频的音频水印嵌入提取算法matlab仿真
本文介绍了结合DCT和扩频技术的音频水印算法,用于在不降低音质的情况下嵌入版权信息。在matlab2022a中实现,算法利用DCT进行频域处理,通过扩频增强水印的隐蔽性和抗攻击性。核心程序展示了水印的嵌入与提取过程,包括DCT变换、水印扩频及反变换步骤。该方法有效且专业,未来研究将侧重于提高实用性和安全性。