2.甲乙双方按照约定构造密钥,双方拥有相同的密钥(一般是一方构造密钥后通知另外一方,此过程不需要通过程序实现,就是双方约定个字符串,但是这个字符串可不是随便设定的,也是通过相关算法获取的)
3.甲方使用密钥对消息做摘要处理,然后将消息和生成的摘要消息一同发送给乙方
4.乙方收到消息后,使用甲方已经公布的摘要算法+约定好的密钥 对收到的消息进行摘要处理。然后比对自己的摘要消息和甲方发过来的摘要消息。甄别消息是否是甲方发送过来的。
MAC算法的实现:
算法 摘要长度 备注HmacMD5 128 JAVA6实现
HmacSHA1 160 JAVA6实现
HmacSHA256 256 JAVA6实现
HmacSHA384 384 JAVA6实现
HmacSHA512 512 JAVA6实现
HmacMD2 128 BouncyCastle实现
HmacMD4 128 BouncyCastle实现
HmacSHA224 224 BouncyCastle实现
Java代码实现:
import java.math.BigInteger; 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 HMAC { public static final String src = "hmac test"; public static void main(String[] args) { jdkHmacMD5(); bcHmacMD5(); } // 用jdk实现: public static void jdkHmacMD5() { try { // 初始化KeyGenerator KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5"); // 产生密钥 SecretKey secretKey = keyGenerator.generateKey(); // 获取密钥 // byte[] key = secretKey.getEncoded(); byte[] key = Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e'}); // 还原密钥 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(); } } // 用bouncy castle实现: public static void bcHmacMD5() { HMac hmac = new HMac(new MD5Digest()); // 必须是16进制的字符,长度必须是2的倍数 hmac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("123456789abcde"))); hmac.update(src.getBytes(), 0, src.getBytes().length); // 执行摘要 byte[] hmacMD5Bytes = new byte[hmac.getMacSize()]; hmac.doFinal(hmacMD5Bytes, 0); BigInteger bigInteger = new BigInteger(1,hmacMD5Bytes); System.out.println("bc hmacMD5:" + bigInteger.toString(16)); } } 参考文章常用消息摘要算法介绍
消息摘要算法-MAC系列