MD5、SHA1、HMAC、HMAC_SHA1区别 MD5 MD5 – message-digest algorithm 5(信息-摘要算法)缩写,是一种不可逆的加密算法,对任何字符串都可以加密成一段唯一的固定长度的代码。可以是128位。 MD5码可以唯一地代码原信息的特征,通常用于密码的加密存储,数字签名,文件完整性验证等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public static byte [] encryptMD5(byte [] data) throws Exception { MessageDigest md5 = MessageDigest.getInstance(KEY_MD5); md5.update(data); return md5.digest () ; }
SHA1 SHA(Secure Hash Algorithm,安全散列算法),较MD5更安全。 SHA1是由NISTNSA设计,对长度小于264的输入,产生长度为160bit的散列值,可穷举性(brute-force )更好。SHA-1是由美国标准技术局(NIST)颁布的国家标准,是一种应用最为广泛的Hash函数算法,也是 目前最先进的加密技术,被政府部门和私营业主用来处理敏感信息。也常用于验证文件有没有被篡改。
1 2 3 4 5 6 7 public static byte [] encryptSHA(byte [] data) throws Exception { MessageDigest sha = MessageDigest.getInstance(KEY_SHA); sha.update(data); return sha.digest () ; }
HMAC_SHA1 HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code, 散列消息鉴别码),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生产一个消息摘要作为输出。消息鉴别码实现鉴别的原理是, 用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个 固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。
HMAC_SHA1需要一个密钥,而SHA1不需要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public static String initMacKey () throws Exception { Keygenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC); SecretKey secretKey = keyGenerator.geterateKey(); return encryptBASE64(secretKey.getEncoded()); } public static byte [] encryptHMAC(byte [] data, String key) throws Exception { SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); return mac.doFinal (data) ; }
CRC CRC的全称为CyclicRedundancyCheck,中文名称为循环冗余校验。它是一类重要的线性分组码,编码和解码方法 简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。
BASE64 按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种 不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent brbitrary sequences of octets in a form that need not be humamly readable.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public static byte[] decryptBASE64(String key) throws Exception { return (new BASE64Decoder()).decodeBuffer(key); } public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); }
## hash算法的作用
MD5Hash算法的“数字指纹”,使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法,不少Unix 系统有提供计算md5checksum的命令。
Hash算法也是现代密码体系中的一个重要组成部分,由于非对称算法的运算速度较慢,所以在数字签名协议中, 单项散列函数扮演了一个重要的角色。对Hash值,又称”数字摘要”进行数字签名,在统计上可以任务与对文件 本身进行数字签名是等效的。
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 import java.security.MessageDigest; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public abstract class Coder { public static final String KEY_SHA = "SHA" ; public static final String KEY_MD5 = "MD5" ; public static final String KEY_MAC = "HmacMD5" ; public static byte [] decryptBASE64(String key) throws Exception { return (new BASE64Decoder()).decodeBuffer(key); } public static String encryptBASE64 (byte [] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); } public static byte [] encryptMD5(byte [] data) throws Exception { MessageDigest md5 = MessageDigest.getInstance(KEY_MD5); md5.update(data); return md5.digest () ; } public static byte [] encryptSHA(byte [] data) throws Exception { MessageDigest sha = MessageDigest.getInstance(KEY_SHA); sha.update(data); return sha.digest () ; } public static String initMacKey () throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC); SecretKey secretKey = keyGenerator.generateKey(); return encryptBASE64(secretKey.getEncoded()); } public static byte [] encryptHMAC(byte [] data, String key) throws Exception { SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); return mac.doFinal (data) ; } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 import static org.junit.Assert.*;import org.junit.Test; public class CoderTest { @Test public void test() throws Exception { String inputStr = "简单加密" ; System.err.println ("原文:/n" + inputStr); byte [] inputData = inputStr.getBytes(); String code = Coder.encryptBASE64(inputData); System.err.println ("BASE64加密后:/n" + code); byte [] output = Coder.decryptBASE64(code); String outputStr = new String (output); System.err.println ("BASE64解密后:/n" + outputStr); assertEquals(inputStr, outputStr); assertArrayEquals(Coder.encryptMD5(inputData), Coder .encryptMD5(inputData)); assertArrayEquals(Coder.encryptSHA(inputData), Coder .encryptSHA(inputData)); String key = Coder.initMacKey(); System.err.println ("Mac密钥:/n" + key ); assertArrayEquals(Coder.encryptHMAC(inputData, key ), Coder.encryptHMAC( inputData, key )); BigInteger md5 = new BigInteger(Coder.encryptMD5(inputData)); System.err.println ("MD5:/n" + md5.toString(16 )); BigInteger sha = new BigInteger(Coder.encryptSHA(inputData)); System.err.println ("SHA:/n" + sha.toString(32 )); BigInteger mac = new BigInteger(Coder.encryptHMAC(inputData, inputStr)); System.err.println ("HMAC:/n" + mac.toString(16 )); } }
参考
加密算法中BASE64、MD5、SHA、HMAC等之间的区别