如何从数据库中储存和使用shiro的盐 [英] How to stock and use a shiro's salt from database
问题描述
我在申请中使用shiro验证。我使用哈希密码盐和我存储他们在我的数据库像这样:
私人用户createUserWithHashedPassword(String inName,String inFirstName ,String inLastName,String inPassword){
ByteSource salt = randomNumberGenerator.nextBytes(32);
byte [] byteTabSalt = salt.getBytes();
String strSalt = byteArrayToHexString(byteTabSalt);
String hashedPasswordBase64 = new Sha256Hash(inPassword,salt,1024).toBase64();
return new User(inName,inFirstName,inLastName,hashedPasswordBase64,strSalt);
}
我在数据库中存储一个字符串。现在在我的领域,我想从数据库中获取我的数据,我使用一个transactionnal服务。但是我的盐是一个Strong,所以我想让它返回作为ByteSource类型与静态方法:
ByteSource byteSourceSalt = Util。字节(salt); //其中盐是一个字符串
但是当我创建我的SaltedAuthenticationInfo时,它不auth。 / p>
我想我的问题是从我的转换方法:
byteArrayToHexString(byte [] bArray){
StringBuffer buffer = new StringBuffer();
for(byte b:bArray){
buffer.append(Integer.toHexString(b));
buffer.append();
}
return buffer.toString()。toUpperCase();
}
感谢您的帮助。
如优秀的答案中所述 http://stackoverflow.com/a/ 20206115/603901 ,Shiro的DefaultPasswordService已为每个密码生成唯一的盐。
但是,没有必要实现一个自定义的PasswordService来添加一个私有盐有时称为胡椒)到每用户盐。私有盐可以在shiro.ini中配置:
[main]
hashService = org.apache.shiro.crypto .hash.DefaultHashService
hashService.hashIterations = 500000
hashService.hashAlgorithmName = SHA-256
hashService.generatePublicSalt = true
#privateSalt需要在shiro.ini中进行base64编码,但是不在Java代码中
hashService.privateSalt = myVERYSECRETBase64EncodedSalt
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordService = org.apache.shiro.authc.credential .DefaultPasswordService
passwordService.hashService = $ hashService
passwordMatcher.passwordService = $ passwordService
用于生成匹配密码的Java代码hash:
DefaultHashService hashService = new DefaultHashService
hashService.setHashIterations(HASH_ITERATIONS); // 500000
hashService.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
hashService.setPrivateSalt(new SimpleByteSource(PRIVATE_SALT)); //与shiro.ini中的盐相同,但没有base64编码。
hashService.setGeneratePublicSalt(true);
DefaultPasswordService passwordService = new DefaultPasswordService();
passwordService.setHashService(hashService);
String encryptedPassword = passwordService.encryptPassword(PasswordForThisUser);
生成的哈希如下所示:
$ shiro1 $ SHA-256 $ 500000 $ An4HRyqMJlZ58utACtyGDQ == $ nKbIY9Nd9vC89G4SjdnDfka49mZiesjWgDsO / 4Ly4Qs =
私有盐不存储在数据库中,这使得如果对手获得对数据库转储的访问,就很难破解密码。
is used using shiro-1.2.2
感谢 https://github.com/Multifarious/shiro-jdbi-realm/blob/master/src/test/resources/shiro.ini 有关shiro.ini
语法的帮助
I use shiro in application for the authenticate. I use hashed password with a salt and I store them in my database like this :
private User createUserWithHashedPassword(String inName, String inFirstName, String inLastName, String inPassword){
ByteSource salt = randomNumberGenerator.nextBytes(32);
byte[] byteTabSalt = salt.getBytes();
String strSalt = byteArrayToHexString(byteTabSalt);
String hashedPasswordBase64 = new Sha256Hash(inPassword, salt, 1024).toBase64();
return new User(inName,inFirstName,inLastName,hashedPasswordBase64,strSalt);
}
I store the salt with a String in my database. Now in my realm I want to get back my datas from the database, I use a transactionnal service for this. But my salt is a Strong so I want it to turn back as ByteSource type with the static method :
ByteSource byteSourceSalt = Util.bytes(salt); //where the salt is a String
But when I create my SaltedAuthenticationInfo it doesn't auth.
I think my problem is from my convert method :
private String byteArrayToHexString(byte[] bArray){
StringBuffer buffer = new StringBuffer();
for(byte b : bArray) {
buffer.append(Integer.toHexString(b));
buffer.append(" ");
}
return buffer.toString().toUpperCase();
}
Thanks for your help.
As mentioned in the excellent answer http://stackoverflow.com/a/20206115/603901, Shiro's DefaultPasswordService already generates unique salts for each password.
However, there is no need to implement a custom PasswordService to add a private salt (sometimes called "pepper") to the per-user salts. Private salt can be configured in shiro.ini:
[main]
hashService = org.apache.shiro.crypto.hash.DefaultHashService
hashService.hashIterations = 500000
hashService.hashAlgorithmName = SHA-256
hashService.generatePublicSalt = true
# privateSalt needs to be base64-encoded in shiro.ini but not in the Java code
hashService.privateSalt = myVERYSECRETBase64EncodedSalt
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordService.hashService = $hashService
passwordMatcher.passwordService = $passwordService
Java code for generating a matching password hash:
DefaultHashService hashService = new DefaultHashService();
hashService.setHashIterations(HASH_ITERATIONS); // 500000
hashService.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
hashService.setPrivateSalt(new SimpleByteSource(PRIVATE_SALT)); // Same salt as in shiro.ini, but NOT base64-encoded.
hashService.setGeneratePublicSalt(true);
DefaultPasswordService passwordService = new DefaultPasswordService();
passwordService.setHashService(hashService);
String encryptedPassword = passwordService.encryptPassword("PasswordForThisUser");
The resulting hash looks like this:
$shiro1$SHA-256$500000$An4HRyqMJlZ58utACtyGDQ==$nKbIY9Nd9vC89G4SjdnDfka49mZiesjWgDsO/4Ly4Qs=
The private salt is not stored in the database, which makes it harder to crack the passwords if an adversary gains access to a database dump.
This example was created using shiro-1.2.2
Thanks to https://github.com/Multifarious/shiro-jdbi-realm/blob/master/src/test/resources/shiro.ini for help with the syntax for shiro.ini
这篇关于如何从数据库中储存和使用shiro的盐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!