散列算法
散列算法一般用于生成數(shù)據(jù)的摘要信息,是一種不可逆的算法,一般適合存儲密碼之類的數(shù)據(jù),常見的散列算法如MD5、SHA等。一般進行散列時最好提供一個salt(鹽),比如加密密碼“admin”,產生的散列值是“21232f297a57a5a743894a0e4a801fc3”,可以到一些md5解密網站很容易的通過散列值得到密碼“admin”,即如果直接對密碼進行散列相對來說破解更容易,此時我們可以加一些只有系統(tǒng)知道的干擾數(shù)據(jù),如用戶名和ID(即鹽);這樣散列的對象是“密碼+用戶名+ID”,這樣生成的散列值相對來說更難破解。
String str = "hello";
String salt = "123";
String md5 = new Md5Hash(str, salt).toString();
如上代碼通過鹽“123”MD5散列“hello”。另外散列時還可以指定散列次數(shù),如2次表示:md5(md5(str)):“new Md5Hash(str, salt, 2).toString()”。
常見的加密算法還有:SHA256、SHA1、SHA512算法。
Shiro還提供了通用的散列支持:
String str = "hello";
String salt = "123";
//內部使用MessageDigest
String simpleHash = new SimpleHash("SHA-1", str, salt).toString();
為了方便使用,Shiro提供了HashService,默認提供了DefaultHashService實現(xiàn)。
@Test
public void testdemo() {
DefaultHashService hashService = new DefaultHashService(); //默認算法SHA-512
hashService.setHashAlgorithmName("SHA-512");
hashService.setPrivateSalt(new SimpleByteSource("123")); //私鹽,默認無
hashService.setGeneratePublicSalt(true);//是否生成公鹽,默認false
hashService.setRandomNumberGenerator(new SecureRandomNumberGenerator());//用于生成公鹽。默認就這個
hashService.setHashIterations(1); //生成Hash值的迭代次數(shù)
HashRequest request = new HashRequest.Builder()
.setAlgorithmName("MD5").setSource(ByteSource.Util.bytes("hello"))
.setSalt(ByteSource.Util.bytes("123")).setIterations(2).build();
String hex = hashService.computeHash(request).toHex();
}
1、首先創(chuàng)建一個DefaultHashService,默認使用SHA-512算法;
2、可以通過hashAlgorithmName屬性修改算法;
3、可以通過privateSalt設置一個私鹽,其在散列時自動與用戶傳入的公鹽混合產生一個新鹽;
4、可以通過generatePublicSalt屬性在用戶沒有傳入公鹽的情況下是否生成公鹽;
5、可以設置randomNumberGenerator用于生成公鹽;
6、可以設置hashIterations屬性來修改默認加密迭代次數(shù);
7、需要構建一個HashRequest,傳入算法、數(shù)據(jù)、公鹽、迭代次數(shù)。
加密/解密
AES算法實現(xiàn):
/**
* 加密/解密
*/
@Test
public void testAesCipherService() {
AesCipherService aesCipherService = new AesCipherService();
aesCipherService.setKeySize(128);//設置key長度
//生成key
Key key = aesCipherService.generateNewKey();
String text = "hello";
//加密
String encrptText = aesCipherService.encrypt(text.getBytes(), key.getEncoded()).toHex();
//解密
String text2 = new String(aesCipherService.decrypt(Hex.decode(encrptText), key.getEncoded()).getBytes());
Assert.assertEquals(text, text2);
System.out.println(text);
System.out.println(encrptText);
System.out.println(text2);
}
