昊天
java加密算法简要介绍
本篇内容简要介绍
BASE64
、
MD5
、
SHA
、
HMAC
几种加密算法。
BASE64
编码算法不算是真正的加密算法。
MD5
、
SHA
、
HMAC
这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。
BASE64
按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)
常见于邮件、http加密,截取http信息,你就会发现登录操作的用户名、密码字段通过BASE64加密的。
通过java代码实现如下:
Java代码
/**
* BASE64解密
*
* @param key
* @return
* @throws Exception
*/
public
static
byte
[] decryptBASE64(String key)
throws
Exception {
return
(
new
BASE64Decoder()).decodeBuffer(key);
}
/**
* BASE64加密
*
* @param key
* @return
* @throws Exception
*/
public
static
String encryptBASE64(
byte
[] key)
throws
Exception {
return
(
new
BASE64Encoder()).encodeBuffer(key);
}
主要就是BASE64Encoder、BASE64Decoder两个类,我们只需要知道使用对应的方法即可。另,BASE加密后产生的字节位数是8的倍数,如果不够位数以
=
符号填充。
MD5
MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文件是否一致的。
通过java代码实现如下:
Java代码
/**
* MD5加密
*
* @param data
* @return
* @throws Exception
*/
public
static
byte
[] encryptMD5(
byte
[] data)
throws
Exception {
MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
md5.update(data);
return
md5.digest();
}
通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给BASE64再加密一把,得到相应的字符串。
SHA
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了,
但是SHA仍然是公认的安全加密算法,较之MD5更为安全。
通过java代码实现如下:
Java代码
/**
* SHA加密
*
* @param data
* @return
* @throws Exception
*/
public
static
byte
[] encryptSHA(
byte
[] data)
throws
Exception {
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
sha.update(data);
return
sha.digest();
}
}
HMAC
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。
通过java代码实现如下:
Java代码
/**
* 初始化HMAC密钥
*
* @return
* @throws Exception
*/
public
static
String initMacKey()
throws
Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
SecretKey secretKey = keyGenerator.generateKey();
return
encryptBASE64(secretKey.getEncoded());
}
/**
* HMAC加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
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);
}
给出一个完整类,如下:
Java代码
import
java.security.MessageDigest;
import
javax.crypto.KeyGenerator;
import
javax.crypto.Mac;
import
javax.crypto.SecretKey;
import
sun.misc.BASE64Decoder;
import
sun.misc.BASE64Encoder;
/**
* 基础加密组件
*
* @author 梁栋
* @version 1.0
* @since 1.0
*/
public
abstract
class
Coder {
public
static
final
String KEY_SHA =
"SHA"
;
public
static
final
String KEY_MD5 =
"MD5"
;
/**
* MAC算法可选以下多种算法
*
* <pre>
* HmacMD5
* HmacSHA1
* HmacSHA256
* HmacSHA384
* HmacSHA512
* </pre>
*/
public
static
final
String KEY_MAC =
"HmacMD5"
;
/**
* BASE64解密
*
* @param key
* @return
* @throws Exception
*/
public
static
byte
[] decryptBASE64(String key)
throws
Exception {
return
(
new
BASE64Decoder()).decodeBuffer(key);
}
/**
* BASE64加密
*
* @param key
* @return
* @throws Exception
*/
public
static
String encryptBASE64(
byte
[] key)
throws
Exception {
return
(
new
BASE64Encoder()).encodeBuffer(key);
}
/**
* MD5加密
*
* @param data
* @return
* @throws Exception
*/
public
static
byte
[] encryptMD5(
byte
[] data)
throws
Exception {
MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
md5.update(data);
return
md5.digest();
}
/**
* SHA加密
*
* @param data
* @return
* @throws Exception
*/
public
static
byte
[] encryptSHA(
byte
[] data)
throws
Exception {
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
sha.update(data);
return
sha.digest();
}
/**
* 初始化HMAC密钥
*
* @return
* @throws Exception
*/
public
static
String initMacKey()
throws
Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
SecretKey secretKey = keyGenerator.generateKey();
return
encryptBASE64(secretKey.getEncoded());
}
/**
* HMAC加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
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);
}
}
再给出一个测试类:
Java代码
import
static
org.junit.Assert.*;
import
org.junit.Test;
/**
*
* @author 梁栋
* @version 1.0
* @since 1.0
*/
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);
// 验证BASE64加密解密一致性
assertEquals(inputStr, outputStr);
// 验证MD5对于同一内容加密是否一致
assertArrayEquals(Coder.encryptMD5(inputData), Coder
.encryptMD5(inputData));
// 验证SHA对于同一内容加密是否一致
assertArrayEquals(Coder.encryptSHA(inputData), Coder
.encryptSHA(inputData));
String key = Coder.initMacKey();
System.err.println(
"Mac密钥:\n"
+ key);
// 验证HMAC对于同一内容,同一密钥加密是否一致
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
));
}
}
控制台输出:
Console代码
原文:
简单加密
BASE64加密后:
566A5Y2V5Yqg5a+G
BASE64解密后:
简单加密
Mac密钥:
uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke
pBIpkd7QHg==
MD5:
-550b4d90349ad4629462113e7934de56
SHA:
91k9vo7p400cjkgfhjh0ia9qthsjagfn
HMAC:
2287d192387e95694bdbba2fa941009a
BASE64的加密解密是双向的,可以求反解。
MD5、SHA以及HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。其中HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。
单向加密的用途主要是为了校验数据在传输过程中是否被修改。
posted on 2011-11-12 15:19
昊天
阅读(1743)
评论(0)
编辑
收藏
所属分类:
加密
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理
导航
首页
新随笔
联系
聚合
管理
<
2011年11月
>
日
一
二
三
四
五
六
30
31
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
1
2
3
4
5
6
7
8
9
10
统计
随笔 - 61
文章 - 0
评论 - 9
引用 - 0
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔分类
EHCache(3)
(rss)
hadoop(1)
(rss)
hibernate(1)
(rss)
java(7)
(rss)
javascript(1)
(rss)
Jboss(2)
(rss)
Jfreechart(1)
(rss)
JMS(1)
(rss)
Jquery(2)
(rss)
JVM(3)
(rss)
lucence(3)
(rss)
memcached(9)
(rss)
mina(2)
(rss)
oracle(6)
(rss)
Quartz(3)
(rss)
spring(3)
(rss)
SSO(1)
(rss)
struts(2)
(rss)
UML(2)
(rss)
webservice(1)
(rss)
加密(1)
(rss)
大数据(3)
(rss)
程序人生(2)
(rss)
随笔档案
2016年12月 (3)
2013年8月 (1)
2013年3月 (2)
2013年1月 (7)
2012年12月 (4)
2012年6月 (2)
2012年4月 (5)
2012年3月 (1)
2012年2月 (5)
2012年1月 (3)
2011年11月 (1)
2011年10月 (9)
2011年9月 (1)
2011年7月 (3)
2011年5月 (6)
2011年3月 (5)
2011年2月 (2)
2010年10月 (1)
搜索
最新评论
1. re: spring cron表达式
你写的好乱
--吴长青
2. re: EhCache使用详细介绍
厉害!!!
--梦飞
3. re: jQuery文本框字符限制插件 - Textarea Counter
评论内容较长,点击标题查看
--asdf
4. re: spring + ibatis 多数据源事务(分布式事务)管理配置方法(转)[未登录]
需要帮助
--韩磊
5. re: spring + ibatis 多数据源事务(分布式事务)管理配置方法(转)[未登录]
请问程序里面是如何切换的啊
--韩磊
阅读排行榜
1. spring cron表达式 (44769)
2. 查看、分析memcached使用状态(42389)
3. Oracle创建表时Storage参数具体含义(20338)
4. memcached的总结和分布式一致性hash(11456)
5. Java annotation 自定义注释@interface的用法 (7857)
评论排行榜
1. jQuery文本框字符限制插件 - Textarea Counter(3)
2. spring + ibatis 多数据源事务(分布式事务)管理配置方法(转)(2)
3. ReentrantLock和内部锁的性能对比(转) (1)
4. EhCache使用详细介绍(1)
5. j2ee中使用Spring集成quartz计划任务(1)