信息摘要算法 MessageDigestUtil

package com.xgh.message.digest.test;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.SecureRandom;

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

import junit.framework.TestCase;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/***
 * 单向加密方法    
 *   
 * MessageDigest 类提供【信息摘要算法】的功能,
 * 如HMAC、MD2、MD4、MD5、SHA-1、SHA-256、RIPEMD128、RIPEMD160。
 * 信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。 
 * @author xgh
 * 
 *==================================================
 *速度排名:MD4 > MD5 > RIPEMD-128 > SHA-1 > REPEMD-160
 *按照《应用密码学手册》提供的表格数据为:
 *MD4 长度 128 相对速度 1
 *MD5 长度 128 相对速度 0.68
 *REPEMD-128 长度 128 相对速度 0.39
 *SHA-1 长度 160 相对速度 0.29
 *REPEMD-160 长度 160 相对速度 0.24
 *==================================================
 *结论:
 *又要安全又要速度,选择MD5
 *追求安全,不在意速度,相信传说,不相信阴谋论,选择SHA系列
 *追求速度,安全次之,可以选择MD4。
 *==================================================
 */
public class MessageDigestUtil  extends TestCase{

	
	/***
	 * MD5摘要生成
	 * MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写
	 * md5摘要算法算返回的数据长度为128个位,即16个字节。
	 * @throws Exception
	 */
	public void testEncryptMD5() throws Exception { 
		String message ="Hell,在我心中,也许";
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		md5.update(message.getBytes());
		//md5摘要算法算返回的数据长度为128个位,即16个字节。
		byte[] digestbytes = md5.digest();
		System.out.println("md5摘要原数据:"+message);
		System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");
		System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));
		System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));
		System.out.println("--------------md5 end-----------------------");
	}

	/***
	 * SHA摘要生成
	 * SHA(Secure Hash Algorithm,安全散列算法),
	 * sha摘要算法算返回的数据长度为160个位,即20个字节。
	 * @throws Exception
	 */
	public void testEncryptSHA() throws Exception { 
		String message ="Hell,在我心中,也许";
		MessageDigest md5 = MessageDigest.getInstance("SHA");
		md5.update(message.getBytes());
		//md5摘要算法算返回的数据长度为128个位,即16个字节。
		byte[] digestbytes = md5.digest();
		System.out.println("sha摘要原数据:"+message);
		System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");
		System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));
		System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));
		System.out.println("--------------sha end-----------------------");
	}
	
	/***
	 * SHA1摘要生成
	 * SHA(Secure Hash Algorithm,安全散列算法),
	 * sha1摘要算法算返回的数据长度为160个位,即20个字节。
	 * @throws Exception
	 */
	public void testEncryptSHA1() throws Exception { 
		String message ="Hell,在我心中,也许";
		MessageDigest md5 = MessageDigest.getInstance("SHA-1");
		md5.update(message.getBytes());
		//md5摘要算法算返回的数据长度为128个位,即16个字节。
		byte[] digestbytes = md5.digest();
		System.out.println("sha1摘要原数据:"+message);
		System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");
		System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));
		System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));
		System.out.println("--------------sha1 end-----------------------");
	}
	
	/***
	 * SHA256摘要生成
	 * SHA(Secure Hash Algorithm,安全散列算法),
	 * sha256摘要算法算返回的数据长度为160个位,即20个字节。
	 * @throws Exception
	 */
	public void testEncryptSHA256() throws Exception { 
		String message ="Hell,在我心中,也许";
		MessageDigest md5 = MessageDigest.getInstance("SHA-256");
		md5.update(message.getBytes());
		//md5摘要算法算返回的数据长度为128个位,即16个字节。
		byte[] digestbytes = md5.digest();
		System.out.println("sha265摘要原数据:"+message);
		System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");
		System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));
		System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));
		System.out.println("--------------sha256 end-----------------------");
	}
	
	/***
	 * SHA512摘要生成
	 * SHA(Secure Hash Algorithm,安全散列算法),
	 * sha512摘要算法算返回的数据长度为160个位,即20个字节。
	 * @throws Exception
	 */
	public void testEncryptSHA512() throws Exception { 
		String message ="Hell,在我心中,也许";
		MessageDigest md5 = MessageDigest.getInstance("SHA-512");
		md5.update(message.getBytes());
		//md5摘要算法算返回的数据长度为128个位,即16个字节。
		byte[] digestbytes = md5.digest();
		System.out.println("sha512摘要原数据:"+message);
		System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");
		System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));
		System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));
		System.out.println("--------------sha512 end-----------------------");
	}
	
	/***
	 * Md5摘要后,将字节摘要字节组转16进制数组
	 * @param input
	 * @return
	 */
	public String testMD5ToHex() throws Exception{ 
		String data = "sfs有桂林地村要地wecllo";
		// 获得MD5摘要算法的 MessageDigest 对象             
	     MessageDigest mdInst = MessageDigest.getInstance("MD5");             
	     // 使用指定的字节更新摘要             
	     mdInst.update(data.getBytes());             
	     // 获得摘要密文             
	     byte[] md = mdInst.digest();             
	     // 把密文转换成十六进制的字符串形式             
	     StringBuffer hexString = new StringBuffer();             
	     // 字节数组转换为 十六进制 数             
	     for (int i = 0; i < md.length; i++) {                 
	     String shaHex = Integer.toHexString(md[i] & 0xFF);   
	       if (shaHex.length() < 2) {//不足2位16进制位,则补0,一个字节是2位16进制位                                   
	          hexString.append(0);                 
	       }                 
	       hexString.append(shaHex);             
	     }             
	     return hexString.toString(); 
	}
	
	/***
	 * SHA-1摘要后,将字节摘要字节组转16进制数组
	 * @param input
	 * @return
	 */
	public String testSHA1ToHex() throws Exception{ 
		String data = "sfs有桂林地村要地wecllo";
		// 获得MD5摘要算法的 MessageDigest 对象             
	     MessageDigest mdInst = MessageDigest.getInstance("SHA-1");             
	     // 使用指定的字节更新摘要             
	     mdInst.update(data.getBytes());             
	     // 获得摘要密文             
	     byte[] md = mdInst.digest();             
	     // 把密文转换成十六进制的字符串形式             
	     StringBuffer hexString = new StringBuffer();             
	     // 字节数组转换为 十六进制 数             
	     for (int i = 0; i < md.length; i++) {                 
	       int r = md[i] & 0xf;   
	       if (r <= 0xf) {//不足2位16进制位,则补0,一个字节是2位16进制位                    
	          hexString.append(0);                 
	       }                 
	       hexString.append(Integer.toHexString(r));             
	     }             
	     return hexString.toString(); 
	}
	
	/***
	 * HMAC摘要生成  单向加密算法
	 * HMAC摘要算法算返回的数据长度为128个位,即16个字节。
	 * HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。
	 * 消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。
	 * 使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。
	 * @throws Exception
     * HMAC算法可选以下多种算法   :
     *   HmacMD5   
     *   HmacSHA1   
     *   HmacSHA256   
     *   HmacSHA384   
     *   HmacSHA512  
     * 
     */  

	public void testEncryptHMAC() throws Exception { 
		 String message ="Hell,在我心中,也许";
		 KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA1");  
         SecretKey secretKey1 = keyGenerator.generateKey();  
         //Mac密钥
		 String key =  new BASE64Encoder().encode((secretKey1.getEncoded()));  
		 System.out.println("Mac密钥:"+key);
         
		 SecretKey secretKey2 = new SecretKeySpec(new BASE64Decoder().decodeBuffer(key), "HmacSHA1");   
		 //返回此密钥编码格式的名称。
		 //System.out.println(secretKey1.getFormat());
		 Mac mac = Mac.getInstance(secretKey2.getAlgorithm());   
		 mac.init(secretKey2);   
		 byte[] digestbytes = mac.doFinal(message.getBytes());   

		System.out.println("HMAC摘要原数据:"+message);
		System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");
		System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));
		System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));
		System.out.println("--------------HMAC end-----------------------");
		
	}
	 
	/***
	 * AES 双向加密算法
	 * @param content   待加密内容 
	 * @param password  加密密钥
	 * @return
	 */
	public  byte[] testEncryptAES() throws Exception{ 
		String content = "Hello,明天天气不错";
		String password = "123456";
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128, new SecureRandom(password.getBytes()));
		SecretKey secretKey = kgen.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();
		SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
		Cipher cipher = Cipher.getInstance("AES");// 创建密码器
		byte[] byteContent = content.getBytes("utf-8");
		cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
		byte[] result = cipher.doFinal(byteContent);
		System.out.println("AES加密后的Base64结果:");
		System.out.println(new BASE64Encoder().encode(result));
		return result; // 加密
	}
	
	/***
	 *  AES 双向加密算法
	 * @param content  待解密内容 
	 * @param password 解密密钥
	 * @return
	 */
	public  byte[] testDecryptAES() throws Exception{
		String content = "2M8d6HQ0qtXqSSuL83ILs348ls6C8JlZnfu0UFgCkOw=";
		String password = "123456";
		byte[] contentbyte = new BASE64Decoder().decodeBuffer(content);
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128, new SecureRandom(password.getBytes()));
		SecretKey secretKey = kgen.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();
		SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
		Cipher cipher = Cipher.getInstance("AES");// 创建密码器
		cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
		byte[] result = cipher.doFinal(contentbyte);
		System.out.println("解密结果:");
		System.out.println(new String(result,"UTF-8"));
		return result; // 加密
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值