信息摘要算法 MessageDigestUtil

  1. package com.xgh.message.digest.test;  
  2.   
  3. import java.math.BigInteger;  
  4. import java.security.MessageDigest;  
  5. import java.security.SecureRandom;  
  6.   
  7. import javax.crypto.Cipher;  
  8. import javax.crypto.KeyGenerator;  
  9. import javax.crypto.Mac;  
  10. import javax.crypto.SecretKey;  
  11. import javax.crypto.spec.SecretKeySpec;  
  12.   
  13. import junit.framework.TestCase;  
  14. import sun.misc.BASE64Decoder;  
  15. import sun.misc.BASE64Encoder;  
  16.   
  17. /*** 
  18.  * 单向加密方法     
  19.  *    
  20.  * MessageDigest 类提供【信息摘要算法】的功能, 
  21.  * 如HMAC、MD2、MD4、MD5、SHA-1、SHA-256、RIPEMD128、RIPEMD160。 
  22.  * 信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。  
  23.  * @author xgh 
  24.  *  
  25.  *================================================== 
  26.  *速度排名:MD4 > MD5 > RIPEMD-128 > SHA-1 > REPEMD-160 
  27.  *按照《应用密码学手册》提供的表格数据为: 
  28.  *MD4 长度 128 相对速度 1 
  29.  *MD5 长度 128 相对速度 0.68 
  30.  *REPEMD-128 长度 128 相对速度 0.39 
  31.  *SHA-1 长度 160 相对速度 0.29 
  32.  *REPEMD-160 长度 160 相对速度 0.24 
  33.  *================================================== 
  34.  *结论: 
  35.  *又要安全又要速度,选择MD5 
  36.  *追求安全,不在意速度,相信传说,不相信阴谋论,选择SHA系列 
  37.  *追求速度,安全次之,可以选择MD4。 
  38.  *================================================== 
  39.  */  
  40. public class MessageDigestUtil  extends TestCase{  
  41.   
  42.       
  43.     /*** 
  44.      * MD5摘要生成 
  45.      * MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写 
  46.      * md5摘要算法算返回的数据长度为128个位,即16个字节。 
  47.      * @throws Exception 
  48.      */  
  49.     public void testEncryptMD5() throws Exception {   
  50.         String message ="Hell,在我心中,也许";  
  51.         MessageDigest md5 = MessageDigest.getInstance("MD5");  
  52.         md5.update(message.getBytes());  
  53.         //md5摘要算法算返回的数据长度为128个位,即16个字节。  
  54.         byte[] digestbytes = md5.digest();  
  55.         System.out.println("md5摘要原数据:"+message);  
  56.         System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");  
  57.         System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));  
  58.         System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));  
  59.         System.out.println("--------------md5 end-----------------------");  
  60.     }  
  61.   
  62.     /*** 
  63.      * SHA摘要生成 
  64.      * SHA(Secure Hash Algorithm,安全散列算法), 
  65.      * sha摘要算法算返回的数据长度为160个位,即20个字节。 
  66.      * @throws Exception 
  67.      */  
  68.     public void testEncryptSHA() throws Exception {   
  69.         String message ="Hell,在我心中,也许";  
  70.         MessageDigest md5 = MessageDigest.getInstance("SHA");  
  71.         md5.update(message.getBytes());  
  72.         //md5摘要算法算返回的数据长度为128个位,即16个字节。  
  73.         byte[] digestbytes = md5.digest();  
  74.         System.out.println("sha摘要原数据:"+message);  
  75.         System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");  
  76.         System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));  
  77.         System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));  
  78.         System.out.println("--------------sha end-----------------------");  
  79.     }  
  80.       
  81.     /*** 
  82.      * SHA1摘要生成 
  83.      * SHA(Secure Hash Algorithm,安全散列算法), 
  84.      * sha1摘要算法算返回的数据长度为160个位,即20个字节。 
  85.      * @throws Exception 
  86.      */  
  87.     public void testEncryptSHA1() throws Exception {   
  88.         String message ="Hell,在我心中,也许";  
  89.         MessageDigest md5 = MessageDigest.getInstance("SHA-1");  
  90.         md5.update(message.getBytes());  
  91.         //md5摘要算法算返回的数据长度为128个位,即16个字节。  
  92.         byte[] digestbytes = md5.digest();  
  93.         System.out.println("sha1摘要原数据:"+message);  
  94.         System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");  
  95.         System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));  
  96.         System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));  
  97.         System.out.println("--------------sha1 end-----------------------");  
  98.     }  
  99.       
  100.     /*** 
  101.      * SHA256摘要生成 
  102.      * SHA(Secure Hash Algorithm,安全散列算法), 
  103.      * sha256摘要算法算返回的数据长度为160个位,即20个字节。 
  104.      * @throws Exception 
  105.      */  
  106.     public void testEncryptSHA256() throws Exception {   
  107.         String message ="Hell,在我心中,也许";  
  108.         MessageDigest md5 = MessageDigest.getInstance("SHA-256");  
  109.         md5.update(message.getBytes());  
  110.         //md5摘要算法算返回的数据长度为128个位,即16个字节。  
  111.         byte[] digestbytes = md5.digest();  
  112.         System.out.println("sha265摘要原数据:"+message);  
  113.         System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");  
  114.         System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));  
  115.         System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));  
  116.         System.out.println("--------------sha256 end-----------------------");  
  117.     }  
  118.       
  119.     /*** 
  120.      * SHA512摘要生成 
  121.      * SHA(Secure Hash Algorithm,安全散列算法), 
  122.      * sha512摘要算法算返回的数据长度为160个位,即20个字节。 
  123.      * @throws Exception 
  124.      */  
  125.     public void testEncryptSHA512() throws Exception {   
  126.         String message ="Hell,在我心中,也许";  
  127.         MessageDigest md5 = MessageDigest.getInstance("SHA-512");  
  128.         md5.update(message.getBytes());  
  129.         //md5摘要算法算返回的数据长度为128个位,即16个字节。  
  130.         byte[] digestbytes = md5.digest();  
  131.         System.out.println("sha512摘要原数据:"+message);  
  132.         System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");  
  133.         System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));  
  134.         System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));  
  135.         System.out.println("--------------sha512 end-----------------------");  
  136.     }  
  137.       
  138.     /*** 
  139.      * Md5摘要后,将字节摘要字节组转16进制数组 
  140.      * @param input 
  141.      * @return 
  142.      */  
  143.     public String testMD5ToHex() throws Exception{   
  144.         String data = "sfs有桂林地村要地wecllo";  
  145.         // 获得MD5摘要算法的 MessageDigest 对象               
  146.          MessageDigest mdInst = MessageDigest.getInstance("MD5");               
  147.          // 使用指定的字节更新摘要               
  148.          mdInst.update(data.getBytes());               
  149.          // 获得摘要密文               
  150.          byte[] md = mdInst.digest();               
  151.          // 把密文转换成十六进制的字符串形式               
  152.          StringBuffer hexString = new StringBuffer();               
  153.          // 字节数组转换为 十六进制 数               
  154.          for (int i = 0; i < md.length; i++) {                   
  155.          String shaHex = Integer.toHexString(md[i] & 0xFF);     
  156.            if (shaHex.length() < 2) {//不足2位16进制位,则补0,一个字节是2位16进制位                                     
  157.               hexString.append(0);                   
  158.            }                   
  159.            hexString.append(shaHex);               
  160.          }               
  161.          return hexString.toString();   
  162.     }  
  163.       
  164.     /*** 
  165.      * SHA-1摘要后,将字节摘要字节组转16进制数组 
  166.      * @param input 
  167.      * @return 
  168.      */  
  169.     public String testSHA1ToHex() throws Exception{   
  170.         String data = "sfs有桂林地村要地wecllo";  
  171.         // 获得MD5摘要算法的 MessageDigest 对象               
  172.          MessageDigest mdInst = MessageDigest.getInstance("SHA-1");               
  173.          // 使用指定的字节更新摘要               
  174.          mdInst.update(data.getBytes());               
  175.          // 获得摘要密文               
  176.          byte[] md = mdInst.digest();               
  177.          // 把密文转换成十六进制的字符串形式               
  178.          StringBuffer hexString = new StringBuffer();               
  179.          // 字节数组转换为 十六进制 数               
  180.          for (int i = 0; i < md.length; i++) {                   
  181.            int r = md[i] & 0xf;     
  182.            if (r <= 0xf) {//不足2位16进制位,则补0,一个字节是2位16进制位                      
  183.               hexString.append(0);                   
  184.            }                   
  185.            hexString.append(Integer.toHexString(r));               
  186.          }               
  187.          return hexString.toString();   
  188.     }  
  189.       
  190.     /*** 
  191.      * HMAC摘要生成  单向加密算法 
  192.      * HMAC摘要算法算返回的数据长度为128个位,即16个字节。 
  193.      * HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。 
  194.      * 消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。 
  195.      * 使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。 
  196.      * @throws Exception 
  197.      * HMAC算法可选以下多种算法   : 
  198.      *   HmacMD5    
  199.      *   HmacSHA1    
  200.      *   HmacSHA256    
  201.      *   HmacSHA384    
  202.      *   HmacSHA512   
  203.      *  
  204.      */    
  205.   
  206.     public void testEncryptHMAC() throws Exception {   
  207.          String message ="Hell,在我心中,也许";  
  208.          KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA1");    
  209.          SecretKey secretKey1 = keyGenerator.generateKey();    
  210.          //Mac密钥  
  211.          String key =  new BASE64Encoder().encode((secretKey1.getEncoded()));    
  212.          System.out.println("Mac密钥:"+key);  
  213.            
  214.          SecretKey secretKey2 = new SecretKeySpec(new BASE64Decoder().decodeBuffer(key), "HmacSHA1");     
  215.          //返回此密钥编码格式的名称。  
  216.          //System.out.println(secretKey1.getFormat());  
  217.          Mac mac = Mac.getInstance(secretKey2.getAlgorithm());     
  218.          mac.init(secretKey2);     
  219.          byte[] digestbytes = mac.doFinal(message.getBytes());     
  220.   
  221.         System.out.println("HMAC摘要原数据:"+message);  
  222.         System.out.println("信息摘要长度:"+(digestbytes.length*8)+"位");  
  223.         System.out.println("摘要BigInteger结果:"+new BigInteger(digestbytes));  
  224.         System.out.println("摘要Base64结果:"+new BASE64Encoder().encode(digestbytes));  
  225.         System.out.println("--------------HMAC end-----------------------");  
  226.           
  227.     }  
  228.        
  229.     /*** 
  230.      * AES 双向加密算法 
  231.      * @param content   待加密内容  
  232.      * @param password  加密密钥 
  233.      * @return 
  234.      */  
  235.     public  byte[] testEncryptAES() throws Exception{   
  236.         String content = "Hello,明天天气不错";  
  237.         String password = "123456";  
  238.         KeyGenerator kgen = KeyGenerator.getInstance("AES");  
  239.         kgen.init(128new SecureRandom(password.getBytes()));  
  240.         SecretKey secretKey = kgen.generateKey();  
  241.         byte[] enCodeFormat = secretKey.getEncoded();  
  242.         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");  
  243.         Cipher cipher = Cipher.getInstance("AES");// 创建密码器  
  244.         byte[] byteContent = content.getBytes("utf-8");  
  245.         cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化  
  246.         byte[] result = cipher.doFinal(byteContent);  
  247.         System.out.println("AES加密后的Base64结果:");  
  248.         System.out.println(new BASE64Encoder().encode(result));  
  249.         return result; // 加密  
  250.     }  
  251.       
  252.     /*** 
  253.      *  AES 双向加密算法 
  254.      * @param content  待解密内容  
  255.      * @param password 解密密钥 
  256.      * @return 
  257.      */  
  258.     public  byte[] testDecryptAES() throws Exception{  
  259.         String content = "2M8d6HQ0qtXqSSuL83ILs348ls6C8JlZnfu0UFgCkOw=";  
  260.         String password = "123456";  
  261.         byte[] contentbyte = new BASE64Decoder().decodeBuffer(content);  
  262.         KeyGenerator kgen = KeyGenerator.getInstance("AES");  
  263.         kgen.init(128new SecureRandom(password.getBytes()));  
  264.         SecretKey secretKey = kgen.generateKey();  
  265.         byte[] enCodeFormat = secretKey.getEncoded();  
  266.         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");  
  267.         Cipher cipher = Cipher.getInstance("AES");// 创建密码器  
  268.         cipher.init(Cipher.DECRYPT_MODE, key);// 初始化  
  269.         byte[] result = cipher.doFinal(contentbyte);  
  270.         System.out.println("解密结果:");  
  271.         System.out.println(new String(result,"UTF-8"));  
  272.         return result; // 加密  
  273.     }  
  274. }  


原文地址:https://www.cnblogs.com/jpfss/p/8569312.html