MD5、SHA1和HmacMD5算法的Java实现

版权声明:本文为博主 [小明同学爱思考] 原创文章,转载请注明出处。 https://blog.csdn.net/sinat_22840937/article/details/79772598

JDK、第三方库commons-codec和bouncy-castle均对这些有实现。

MD系列算法实现

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD2Digest;
import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

public class MD {

    private static String srcMsg = "imooc security md";

    public static void main(String[] args) throws NoSuchAlgorithmException {
        jdkMD(srcMsg, "MD5");
        jdkMD(srcMsg, "MD2");

        bcMD(srcMsg, MD5Digest.class);
        bcMD(srcMsg, MD4Digest.class);
        bcMD(srcMsg, MD2Digest.class);
        bcMD4(srcMsg);

        ccMD(srcMsg, "MD5");
        ccMD(srcMsg, "MD2");
        ccMD(srcMsg, "MD4");
    }

    /**
     * JDK MD算法相关实现
     *
     * @param srcMsg 加密消息
     * @param md     支持算法:MD2、MD5
     */
    public static void jdkMD(String srcMsg, String md) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(md);
            byte[] bytes = messageDigest.digest(srcMsg.getBytes());
            String encodedMsg = Hex.encodeHexString(bytes);
            System.out.println(encodedMsg);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * Bouncy Castle MD算法实现
     *
     * @param srcMsg      加密消息
     * @param digestClass 加密算法对应的实现类,支持的有:
     *                    org.bouncycastle.crypto.digests.MD2Digest
     *                    org.bouncycastle.crypto.digests.MD4Digest
     *                    org.bouncycastle.crypto.digests.MD5Digest
     */
    public static void bcMD(String srcMsg, Class<? extends Digest> digestClass) {
        try {
            Digest digest = digestClass.newInstance();
            digest.update(srcMsg.getBytes(), 0, srcMsg.getBytes().length);
            byte[] bytes = new byte[digest.getDigestSize()];
            digest.doFinal(bytes, 0);
            String encodedMsg = org.bouncycastle.util.encoders.Hex.toHexString(bytes);
            System.out.println(encodedMsg);
        } catch (IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
    }

    /**
     * 另一种bouncy castle实现MD4的方式(好像是只有MD4可以这样)
     *
     * @param srcMsg 加密消息
     */
    public static void bcMD4(String srcMsg) {
        try {
            Security.addProvider(new BouncyCastleProvider());
            MessageDigest messageDigest = MessageDigest.getInstance("MD4");
            byte[] bytes = messageDigest.digest(srcMsg.getBytes());
            String encodedMsg = Hex.encodeHexString(bytes);
            System.out.println(encodedMsg);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * commons-codec MD算法实现
     *
     * @param srcMsg 加密消息
     * @param md     支持的加密算法:MD2、MD5
     * @throws NoSuchAlgorithmException
     */
    public static void ccMD(String srcMsg, String md) throws NoSuchAlgorithmException {
        if ("MD5".equals(md)) {
            String encodedMsg = DigestUtils.md5Hex(srcMsg.getBytes());
            System.out.println(encodedMsg);
            return;
        }
        if ("MD2".equals(md)) {
            String encodedMsg = DigestUtils.md2Hex(srcMsg.getBytes());
            System.out.println(encodedMsg);
            return;
        }
        throw new NoSuchAlgorithmException("only support for MD2 and MD5");
    }

}

SHA系列算法的思想

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;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA3Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.digests.SHAKEDigest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

public class SHA {

    private static String srcMsg = "imooc security sha";

    public static void main(String[] args) throws NoSuchAlgorithmException {
        jdkSHA1(srcMsg);

        bcSHA(srcMsg, BouncyCastleSHAEnum.SHA1);
        bcSHA224(srcMsg);

        ccSHA(srcMsg, "SHA1");
        ccSHA(srcMsg, "SH224");
    }

    /**
     * jdk 实现SHA1算法
     *
     * @param srcMsg 加密消息
     */
    public static void jdkSHA1(String srcMsg) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA");
            messageDigest.update(srcMsg.getBytes());
            String encodedMsg = Hex.encodeHexString(messageDigest.digest());
            System.out.println(encodedMsg);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * 第三方库Bouncy Castle实现的SHA算法枚举类
     */
    public enum BouncyCastleSHAEnum {
        SHA1(new SHA1Digest()),
        SHA3(new SHA3Digest()),
        SHA224(new SHA224Digest()),
        SHA256(new SHA256Digest()),
        SHA384(new SHA384Digest()),
        SHA512(new SHA512Digest()),
        SHAKE(new SHAKEDigest()),;

        private Digest digest;

        BouncyCastleSHAEnum(Digest digest) {
            this.digest = digest;
        }

        public Digest getDigest() {
            return digest;
        }
    }

    /**
     * Bouncy Castle实现的SHA算法
     *
     * @param srcMsg 签名消息
     * @param sha    BouncyCastleSHAEnum
     */
    public static void bcSHA(String srcMsg, BouncyCastleSHAEnum sha) {
        Digest digest = sha.getDigest();
        digest.update(srcMsg.getBytes(), 0, srcMsg.getBytes().length);
        byte[] bytes = new byte[digest.getDigestSize()];
        digest.doFinal(bytes, 0);
        String encodedMsg = org.bouncycastle.util.encoders.Hex.toHexString(bytes);
        System.out.println(encodedMsg);
    }

    /**
     * 这种方法适用于SHA224、SHA256、SHA384、SHA512算法,其他可执行算法是指还是通过jdk支持实现的
     *
     * @param srcMsg
     */
    public static void bcSHA224(String srcMsg) {
        try {
            Security.addProvider(new BouncyCastleProvider());
            MessageDigest messageDigest = MessageDigest.getInstance("SHA224");
            byte[] bytes = messageDigest.digest(srcMsg.getBytes());
            String encodedMsg = Hex.encodeHexString(bytes);
            System.out.println(encodedMsg);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * commons-coodec 实现的SHA相关算法(实际是对jdk sha实现的再次封装)
     *
     * @param srcMsg 加密消息
     * @param sha    加密算法
     * @throws NoSuchAlgorithmException
     */
    public static void ccSHA(String srcMsg, String sha) throws NoSuchAlgorithmException {
        if ("SHA1".equals(sha)) {
            String encodedMsg = DigestUtils.sha1Hex(srcMsg);
            System.out.println(encodedMsg);
            return;
        }
        if ("SHA256".equals(sha)) {
            String encodedMsg = DigestUtils.sha256Hex(srcMsg);
            System.out.println(encodedMsg);
            return;
        }
        if ("SHA384".equals(sha)) {
            String encodedMsg = DigestUtils.sha384Hex(srcMsg);
            System.out.println(encodedMsg);
            return;
        }
        if ("SHA512".equals(sha)) {
            String encodedMsg = DigestUtils.sha512Hex(srcMsg);
            System.out.println(encodedMsg);
            return;
        }
        throw new NoSuchAlgorithmException("Only support for [SHA1,SHA256,SHA384,SHA512]");
    }
}

HMAC系列算法的思想

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * MAC: Message Authentication Code
 * HMAc:Keyed-Hash Message Authentication Code
 * 常见的实现算法有:HmacMD2,HmacMD4,HmacMD5,HmacSHA1,HmacSHA224,HmacSHA256,HmacSHA384,HmacSHA512
 */
public class Hmac {

    private static String srcMsg = "imooc security hmac";

    public static void main(String[] args) {
        jdkHmacMD5(srcMsg);
        bcHmacMD5(srcMsg);
    }

    public static void jdkHmacMD5(String srcMsg) {
        try {
            //初始化KeyGenerator
            KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
            //产生密钥
            SecretKey secretKey = keyGenerator.generateKey();
            //获得密钥
//            byte[] key = secretKey.getEncoded();
            byte[] key = Hex.decodeHex(new char[]{'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'});
            //还原密钥
            SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMd5");
            //实例化Mac
            Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());
            //初始化MAC
            mac.init(restoreSecretKey);
            byte[] bytes = mac.doFinal(srcMsg.getBytes());
            String encodedMsg = Hex.encodeHexString(bytes);
            System.out.println(encodedMsg);
        } catch (NoSuchAlgorithmException | InvalidKeyException | DecoderException e) {
            e.printStackTrace();
        }
    }

    public static void bcHmacMD5(String srcMsg) {
        HMac hMac = new HMac(new MD5Digest());
        hMac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("aaaaaaaaaa")));
        hMac.update(srcMsg.getBytes(), 0, srcMsg.getBytes().length);
        byte[] bytes = new byte[hMac.getMacSize()];
        hMac.doFinal(bytes, 0);
        String encodedMsg = Hex.encodeHexString(bytes);
        System.out.println(encodedMsg);
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_22840937/article/details/79772598