Java加密系列之(三)訊息摘要演算法加密
阿新 • • 發佈:2019-02-13
訊息摘要演算法的分類
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×tamp=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();
}
}