本文字数为 5075 字, 预计读完大约需要 15 分钟
消息摘要算法
这里介绍了三种消息摘要算法(MD、SHA、MAC),以及他们的使用方法(包括JDK,Commons Codec和Bouncy Castle的三种使用方法)
[TOC]
消息摘要算法:
验证数据的完整性 数字签名核心算法
- MD(Message Digest)(消息摘要)
- SHA(Secure Hash Algorithm)(安全散列)
- MAC(Message Authentication Code)(消息认证码)
消息摘要算法–MD
- 单向加密的过程
- MD5
- MD2、MD4
- MD家族(128位摘要信息)
- 实现:
算法 | 摘要长度 | 实现方 |
---|---|---|
MD2 | 128 | JDK |
MD4 | 128 | Bouncy Castle(JDK没有提供实现) |
MD5 | 128 | JDK |
MD算法应用
用户注册 –> 对密码进行摘要处理 –> 存到数据库 –> (用户名明文,密码摘要处理)
###例子程序
要进行加密的字符串
String src = "I'm Learing MD"
JDK
/**
* jdk实现MD5加密
* 实现MD2加密只需要将getInstance("MD5")改为getInstance("MD2")即可
*/
public static void jdkMD5() {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md.digest(src.getBytes());//通过digest进行加密
//需要将byte数组转换成16进制
System.out.println("JDK Md5:"+ Hex.encodeHexString(md5Bytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
Bouncy Castle
/**
* bc实现MD4加密
* 实现MD5加密只需要将
* Digest digest = new MD4Digest()改为
* Digest digest = new MD5Digest()即可
*/
public static void bcMD4() {
Digest digest = new MD4Digest();
digest.update(src.getBytes(), 0, src.getBytes().length);
byte[] md4Bytes = new byte[digest.getDigestSize()];
digest.doFinal(md4Bytes, 0);
//将bytes数组转换为16进制
System.out.println("bcMD4:" + org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));
}
利用jdk提供的addProvider方法来为jdk动态添加MD4的实现
/**
* 利用JDK提供的addProvider方法为JDK提供MD4算法
* 为JDK动态添加bc的Provider
*/
public static void bcMD4FromProvider() {
Security.addProvider(new BouncyCastleProvider());//添加Provider,来支持算法
try {
MessageDigest md = MessageDigest.getInstance("MD4");//这时候就可以使用MD4了
byte[] md4Bytes = md.digest(src.getBytes());//通过digest进行加密
//需要将byte数组转换成16进制
System.out.println("bc Md4:"+ org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
Commons Codec
/**
* cc实现MD5加密
* cc其实还是利用了JDK来实现的加密,只是简化了操作,因此它也没有提供MD4的加密算法
*/
public static void ccMD5() {
byte[] md5Bytes = DigestUtils.getMd5Digest().digest(src.getBytes());
System.out.println("cc MD5:" + Hex.encodeHexString(md5Bytes));
}
消息摘要算法–SHA(安全散列算法)
- 固定长度摘要信息
- MD5的继承者(美国国家安全局设计)
- SHA-1、SHA-2(SHA-224,SHA-256,SHA-384,SHA-512)
算法 | 摘要长度 | 实现方 |
---|---|---|
SHA-1 | 160 | JDK |
SHA-224 | 224 | Bouncy Castle |
SHA-256 | 256 | JDK |
SHA-384 | 384 | JDK |
SHA-512 | 512 | JDK |
SHA应用:
浏览器–>设置–>证书–>指纹就是使用SHA进行加密的 发送方–> 公布消息摘要算法 –> 对待发布的消息进行摘要处理 –> 发布摘要消息 –> 发送消息 –> 接收方 –> 消息鉴别
例子程序:
要进行加密的字符串
final String src = "I'm Learning SHA";
jdk
/**
* JDK 实现SHA1加密
* 例如:利用JDK实现SHA-384进行加密就是
* MessageDigest.getInstance("SHA-384");
*/
void jdkSHA1() {
MessageDigest digest = MessageDigest.getInstance("SHA");
digest.update(src.getBytes());
byte[] sha1Bytes = digest.digest();
String sha1Str = Hex.encodeHexString(sha1Bytes);
System.out.println("JDKSHA1Str:" + sha1Str);
}
Bouncy Castle
/**
* 利用bc实现SHA1加密
* 例如:实现SHA-512加密就是new SHA512Digest();
*/
void bcSHA1() {
Digest digest = new SHA1Digest();
digest.update(src.getBytes(), 0, src.getBytes().length);
byte[] sha1Bytes = new byte[digest.getDigestSize()];
digest.doFinal(sha1Bytes,0);
System.out.println("bcSHA1Str:" + org.bouncycastle.util.encoders.Hex.toHexString(sha1Bytes));
}
利用jdk提供的addProvider为jdk动态添加SHA224的实现
/**
* 因为jdk没有提供SHA224的实现因此我们可以 通过addProvider为JDK添加SHA224的实现
*/
public static void jdkSHA224FromBC() {
Security.addProvider(new BouncyCastleProvider());
try {
MessageDigest digest = MessageDigest.getInstance("SHA-224");
byte[] sha224Bytes = digest.digest(src.getBytes());
String sha224Str = Hex.encodeHexString(sha224Bytes);
System.out.println("jdkSHA224FromBCStr:" + sha224Str);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
Commons Codec
/**
* 利用cc进行sha1加密
*/
public static void ccSHA1() {
System.out.println("ccSHA1Str:" + DigestUtils.sha1Hex(src.getBytes()));
System.out.println("ccSHA1Str:" + DigestUtils.sha1Hex(src));
}
消息摘要算法–MAC
- 消息认证码算法
- 兼容了MD和SHA1的特性
- 也叫HMAC算法(含有密钥的散列函数算法)
- 融合MD、SHA
- MD系列: HmacMD2、HmacMD4、HmacMD5
- SHA系列 HmacSHA1,HmacSHA224,HmacSHA256,HmacSHA384,HmacSHA512
实现
|算法 | 摘要长度 | 实现方| |—-|————–|——–| |HmacMD2| 128 | Bouncy Castle| |HmacMD4| 128 | Bouncy Castle| |HmacMD5| 128 | JDK| |HmacSHA1| 160 | JDK| |HmacSHA224| 224 | Bouncy Castle| |HmacSHA256| 256 | JDK| |HmacSHA384| 384 | JDK| |HmacSHA512| 512 | JDK|
应用:
**发送方 –> 公布消息摘要算法 –> 构建密钥 –> 发送密钥 –> 对待发送的消息进行摘要处理 –> 发送消息摘要 –> 发送消息 –> 接收方 –> 消息鉴别 **
例子
要进行加密的字符串
String src = "I'm Learning MAC";
Bouncy Castle
/**
* bc实现HMacMD5加密
*/
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[] hmacBytes = new byte[hmac.getMacSize()];
hmac.doFinal(hmacBytes, 0);
System.out.println("bcHmacMD4Str:" + org.bouncycastle.util.encoders.Hex.toHexString(hmacBytes));
}
jdk
/**
* jdk实现Hmac算法
*/
public static void jdkHmacMD5() {
try {
// KeyGenerator generator = KeyGenerator.getInstance("HmacMD5");//初始化KeyGrnerator
// SecretKey generateKey = generator.generateKey();//产生密钥
// byte[] key = generateKey.getEncoded();//获得密钥
byte[] key = null;//密钥
try {
key = Hex.decodeHex(new char[]{'a','a','a','a','a','a','a','a','a','a'});
} catch (DecoderException e) {
e.printStackTrace();
}
//还原密钥:
SecretKey restoreSecreKt = new SecretKeySpec(key, "HmacMD5");
Mac mac = Mac.getInstance(restoreSecreKt.getAlgorithm());
//初始化mac
mac.init(restoreSecreKt);
byte[] hmacMD5Bytes = mac.doFinal(src.getBytes());//执行摘要
System.out.println("jdkHmacMd5Str:" + Hex.encodeHexString(hmacMD5Bytes));
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
}
其他的一些消息摘要算法:
- RipeMD
- Tiger
- Whirlpool
- GOST3441
- 都是BC提供的实现
本文由 MengFly 创作,采用
知识共享署名4.0
国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:2016-11-25 00:00:00
相关文章推荐: