1. 程式人生 > >Java加密系列之(三)訊息摘要演算法加密

Java加密系列之(三)訊息摘要演算法加密

訊息摘要演算法的分類

MD(Message Digest)訊息摘要

SHA(Secure Hash Algorithm)安全雜湊

MAC(Message Authentication Code)訊息認證碼

訊息摘要演算法的作用

訊息摘要演算法主要有以上3類,這3類演算法的主要作用,都是來驗證資料的完整性,即訊息鑑別

訊息鑑別是指在接收方將原始資訊進行摘要,然後與接收到的摘要資訊進行比對。

訊息摘要演算法是整個數字簽名的核心演算法

訊息摘要演算法——MD

重點介紹MD5,順便介紹下MD家族(MD2、MD4)

MD家族生成的訊息摘要都是128位的,單向加密

package com.tvm.mrz.security.md;

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

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.MessageDigestAlgorithms;
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;

public class MDTest {

	private static String src = "Mr.Z Security Base64";

	public static void jdkMD( String algorithm ) {
		try {
			MessageDigest md = MessageDigest.getInstance( algorithm );
			byte[] mdBytes = md.digest( src.getBytes() );
			System.out.println( md.getProvider().getName() + " " + algorithm + " " + Hex.encodeHexString( mdBytes ) );
		} catch( NoSuchAlgorithmException e ) {
			e.printStackTrace();
		}
	}

	//bcMD的第一種實現方式,基於JDK security框架
	public static void bcMD( String algorithm ) {
		try {
			MessageDigest md = MessageDigest.getInstance( algorithm, new BouncyCastleProvider() );
			byte[] mdBytes = md.digest( src.getBytes() );
			System.out.println( md.getProvider().getName() + " " + algorithm + " " + org.bouncycastle.util.encoders.Hex.toHexString( mdBytes ) );
		} catch( NoSuchAlgorithmException e ) {
			e.printStackTrace();
		}

	}
	
	//只是Provider裡增加了BouncyCastleProvider,優先按Provider順序取演算法
//	public static void bcMD( String algorithm ) {
//		try {
//			Security.addProvider( new BouncyCastleProvider() );
//			MessageDigest md = MessageDigest.getInstance( algorithm );
//			byte[] mdBytes = md.digest( src.getBytes() );
//			System.out.println( md.getProvider().getName() + " " + algorithm + " " + org.bouncycastle.util.encoders.Hex.toHexString( mdBytes ) );
//		} catch( NoSuchAlgorithmException e ) {
//			e.printStackTrace();
//		}
//
//	}

	//bcMD的第二種實現方式
	public static void bcMD( Digest digest ) {
		digest.update( src.getBytes(), 0, src.getBytes().length );
		byte[] result = new byte[ digest.getDigestSize() ];
		digest.doFinal( result, 0 );
		System.out.println( "BC" + " " + digest.getAlgorithmName() + " " + org.bouncycastle.util.encoders.Hex.toHexString( result ) );
	}
	
	// Apache只是在jdk的基礎上進行了高度 的封裝,方便使用,本質是同jdk一樣的。所以cc同jdk一樣,沒有md4實現
	public static void ccMD( String algorithm ) {
		// 第一種方式使用高度封裝的
		if( algorithm == MessageDigestAlgorithms.MD5 ) {
			System.out.println( "CC" + " MD5 " + DigestUtils.md5Hex( src ) );
		}
		if( algorithm == MessageDigestAlgorithms.MD2 ) {
			System.out.println( "CC" + " MD2 " + DigestUtils.md2Hex( src ) );
		}
		// 第二種方式使用jdk框架
		MessageDigest md = DigestUtils.getDigest( algorithm );
		String result = Hex.encodeHexString( md.digest( src.getBytes() ) );
		System.out.println( md.getProvider().getName() + " " + algorithm + " " + result );
	}

	public static void main( String[] args ) {
		jdkMD( "MD5" );
		bcMD( "MD5" );
		bcMD( new MD5Digest() );

		jdkMD( "MD2" );
		bcMD( "MD2" );
		bcMD( new MD2Digest() );

		jdkMD( "MD4" );
		bcMD( "MD4" );
		bcMD( new MD4Digest() );
		
		ccMD( MessageDigestAlgorithms.MD5 );
		ccMD( MessageDigestAlgorithms.MD2 );
		
	}
}

演算法應用:

密碼加密:密碼db中的儲存使用md加密後的密文

訊息摘要演算法——SHA

安全雜湊演算法的簡稱

固定長度摘要資訊

md5的繼承者,在MD4的基礎上演變而來的

SHA-1、SHA-2(SHA-224、SHA-256、SHA-384、SHA-512)

package com.tvm.mrz.security.sha;

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

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

public class SHATest {

	private static String src = "Mr.Z Security Base64";

	// jdk未實現sha224,bc有補充實現,cc基於jdk封裝
	public static void jdkSHA( String algorithm ) {
		try {
			MessageDigest md = MessageDigest.getInstance( algorithm );
			md.update( src.getBytes() );
			byte[] result = md.digest();
			System.out.println( md.getProvider().getName() + " " + algorithm + " " + Hex.encodeHexString( result ) );
		} catch( NoSuchAlgorithmException e ) {
			e.printStackTrace();
		}
	}

	public static void bcSHA( Digest digest ) {
		digest.update( src.getBytes(), 0, src.getBytes().length );
		byte[] shaBytes = new byte[ digest.getDigestSize() ];
		digest.doFinal( shaBytes, 0 );
		System.out.println( "BC" + " " + digest.getAlgorithmName() + " " + org.bouncycastle.util.encoders.Hex.toHexString( shaBytes ) );
	}

	public static void ccSHA( String algorithm ) {
		// 第一種方式使用高度封裝的
		if( algorithm == MessageDigestAlgorithms.SHA_1 ) {
			System.out.println( "CC" + " SHA-1 " + DigestUtils.sha1Hex( src ) );
		}
		// 第二種方式使用jdk框架
		MessageDigest md = DigestUtils.getDigest( algorithm );
		String result = Hex.encodeHexString( md.digest( src.getBytes() ) );
		System.out.println( md.getProvider().getName() + " " + algorithm + " " + result );
	}

	public static void main( String[] args ) {
		jdkSHA( "SHA" );// sha1的演算法名就是SHA
		bcSHA( new SHA1Digest() );
		ccSHA( MessageDigestAlgorithms.SHA_1 );

		jdkSHA( "SHA-256" );
		bcSHA( new SHA256Digest() );
		ccSHA( MessageDigestAlgorithms.SHA_256 );
	}
}

演算法應用:

瀏覽器檢視證書

訊息摘要常用做法:

1.加入約定key

2.增加時間戳

3.排序

http://**?msg=12Hsdvdkjghsajdlkef&timestamp=1309488765

msg:原始訊息+key+時間戳

訊息摘要演算法——MAC

MAC(Message Authentication Code)訊息認證碼

通常把MAC演算法也叫做HMAC演算法

HMAC(keyed-Hash Message Authentication Code)含有金鑰的雜湊函式演算法

融合MD、SHA

——MD系列:HmacMD2、HmacMD4、HmacMD5

——SHA系列:HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512

應用如SecureCRT

package com.tvm.mrz.security.mac;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

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;

public class HmacTest {

	private static String src = "Mr.Z Security Base64";

	public static void jdkHmacMD5() {
		try {
			// 初始化KeyGenerator
			KeyGenerator keyGenerator = KeyGenerator.getInstance( "HmacMD5" );
			// 產生金鑰
			SecretKey secretKey = keyGenerator.generateKey();
			// 獲得金鑰
			// byte[] key = secretKey.getEncoded();
			byte[] key = Hex.decodeHex( "aaaaaaaaaa".toCharArray() );

			// 還原金鑰
			SecretKey restoreSecretKey = new SecretKeySpec( key, "HmacMD5" );
			// 例項化MAC
			Mac mac = Mac.getInstance( restoreSecretKey.getAlgorithm() );
			// 初始化Mac
			mac.init( restoreSecretKey );
			// 執行摘要
			byte[] hmacMD5Bytes = mac.doFinal( src.getBytes() );
			System.out.println( "JDK hmacMD5: " + Hex.encodeHexString( hmacMD5Bytes ) );
		} catch( Exception e ) {
			e.printStackTrace();
		}
	}

	public static void bcHmacMD5() {
		HMac hmac = new HMac( new MD5Digest() );
		hmac.init( new KeyParameter( org.bouncycastle.util.encoders.Hex.decode( "aaaaaaaaaa" ) ) );
		hmac.update( src.getBytes(), 0, src.getBytes().length );

		byte[] hmacMD5Bytes = new byte[ hmac.getMacSize() ];
		hmac.doFinal( hmacMD5Bytes, 0 );

		System.out.println( "BC hmacMD5: " + org.bouncycastle.util.encoders.Hex.toHexString( hmacMD5Bytes ) );
	}

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