消息摘要算法之安全散列算法(SHA)
安全散列算法(Secure Hash Algorithm,SHA)是美国国家标准技术研究所发布的国家标准FIPS PUB 180,最新的标准已经于2008年更新到FIPS PUB 180-3。其中规定了SHA-1,SHA-224,SHA-256,SHA-384,和SHA-512这几种单向散列算法。实际上也可以归为两个大版本SHA-1和SHA-2(SHA-224,SHA-256,SHA-384,SHA-512)。

SHA在MD4之上演化而来,与MD相关算法类似的特点是每种长度的SHA算法拥有各自固定的长度。

JDK也提供了SHA相关算法的实现,使用方法和MD相关方法一致可以参看:消息摘要算法(MDx)。值得注意的是JDK1.7及其之前的版本并未提供SHA-224的实现(如下图),所以Java8以前的版本需要借助第三方的库来实现。
JDK1.7
文章正文图片

JDK1.8
文章正文图片

这里同样推荐BouncyCastle,这个包对进行了完整实现。

另外,借助CommonsCodec可以简化SHA使用的步骤。由于CommonsCodec是对JDK实现的SHA进行进一步的封装,上面说到JDK1.7之前并未提供SHA-224的实现,所以为了适应不同的Java版本,CommonsCodec不含SHA-224相关方法

BouncyCastle及CommonsCodec的Maven依赖配置:
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.58</version>
</dependency>

下面是简单示例,当然,方法重载的版本有很多,这里只是简单测试了一下,根据需求选取适当的方法:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;

public class SHADemo {

    private static String src = "www.devsong.org";

    public static void main(String[] args) {
        try {
            //jdk提供的相关方法测试
            //注意:JDK1.8之前的版本并未提供SHA224的实现,所以你使用Java8之前的版本无法运行此例
            jdkSHA1();
            jdkSHA224();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        
        //BouncyCastle提供的相关方法测试
        bcSHA1();
        bcSHA224();
        
        //CommonsCodec提供的相关方法测试
        //由于CommonsCodec是对JDK提供的实现进行进一步的封装,加之JDK1.8之前并未支持SHA224
        //所以当前CommonsCodec中并没有SHA224相关方法
        ccSHA1();
        ccSHA256();
    }

    /**
     * jdk 提供的 SHA1 算法测试
     * @throws NoSuchAlgorithmException
     */
    public static void jdkSHA1() throws NoSuchAlgorithmException {
        //SHA 即 代表SHA1
        MessageDigest mDigest = MessageDigest.getInstance("SHA");
        byte[] bytes = mDigest.digest(src.getBytes());
        System.out.println("jdkSHA1: " + Hex.encodeHexString(bytes));
    }
    
    /**
     * jdk 提供的 SHA2---SHA-224 算法测试
     * 可以看到使用方法和 MD5 是一样的
     * 其余长度的SHA(SHA256、SHA384、SHA512)使用方法也一致,只需更换getInstance的参数即可
     * @throws NoSuchAlgorithmException
     */
    public static void jdkSHA224() throws NoSuchAlgorithmException {
        MessageDigest mDigest = MessageDigest.getInstance("SHA-224");
        byte[] bytes = mDigest.digest(src.getBytes());
        System.out.println("jdkSHA-224: " + Hex.encodeHexString(bytes));
    }
    
    /**
     * BouncyCastle 提供的SHA1实现测试
     * 同样,使用方法和MD是类似的
     */
    public static void bcSHA1() {
        Digest digest = new SHA1Digest();
        //参数:byte源数组,偏移量(起始位置),长度
        digest.update(src.getBytes(), 0, src.getBytes().length);
        byte bytes[] = new byte[digest.getDigestSize()];
        digest.doFinal(bytes, 0);
        System.out.println("bcSHA1: " + Hex.encodeHexString(bytes));
    }
    
    /**
     * BouncyCastle 提供的SHA224实现测试
     * 其余长度的SHA(SHA256、SHA384、SHA512)使用方法也一致,只需获取不同的Digest对象即可
     */
    public static void bcSHA224() {
        //获取不同对象实现不同算法
        Digest digest = new SHA224Digest();
        digest.update(src.getBytes(), 0, src.getBytes().length);
        byte bytes[] = new byte[digest.getDigestSize()];
        digest.doFinal(bytes, 0);
        System.out.println("bcSHA-224: " + Hex.encodeHexString(bytes));
    }
    
    /**
     * CommonsCodec SHA1 测试
     */
    public static void ccSHA1() {
        System.out.println("ccSHA1: " + DigestUtils.sha1Hex(src));
    }

    /**
     * CommonsCodec SHA256 测试
     * 其余长度(SHA384、SHA512)使用方式也一致
     * 由于JDK1.7及其之前的版本并未实现SHA224,故CommonsCodec当前没有SHA224相关方法
     */
    public static void ccSHA256() {
        System.out.println("ccSHA256: " + DigestUtils.sha256Hex(src));
    }
}

运行结果:
jdkSHA1: 8ea77578d01279d8cc34eae1037e718b08174620
jdkSHA-224: 4af77c223b8d84046687559a17c2b03f4883ed030bc169130e2d38dc
bcSHA1: 8ea77578d01279d8cc34eae1037e718b08174620
bcSHA-224: 4af77c223b8d84046687559a17c2b03f4883ed030bc169130e2d38dc
ccSHA1: 8ea77578d01279d8cc34eae1037e718b08174620
ccSHA256: d20fdc81edcdd2b9eb0bbb684cc7bb8e4b6cee7b727f913af0dfc429febff4f1
It's
欢迎访问本站,欢迎留言、分享、点赞。愿您阅读愉快!
*转载请注明出处,严禁非法转载。
https://www.devsong.org
QQ留言 邮箱留言
头像
引用:
取消回复
提交
涂鸦
涂鸦
热门