Scrypt哈希算法在基于Java的应用程序中广泛使用(因为MD5和其他JDK提供的算法被认为容易被破解)。
JDK没有为Scrypt提供SPI,因此您需要使用BouncyCastle提供程序来支持Scrypt。您可以在项目中使用以下依赖项:
org.bouncycastle:bcprov-jdk18on:1.76
你可以根据你的Java版本使用适当的版本。
现在,你需要决定或生成以下参数来定义你的Scrypt哈希的复杂性:
cpuCost
(整数):定义CPU成本,必须大于1且小于等于65536
memoryCost
(整数):定义内存成本,必须大于1
parallelization
(整数):定义并行化,必须大于1且小于Integer.MAX_VALUE / (128 * memoryCost * 8)
keyLength
(整数):密钥长度必须大于1
salt
(整数):盐长度必须大于1
现在你可以按照给定的盐大小生成盐的字节数组:
SecureRandom random = new SecureRandom();
public byte[] generateKey(int keyLength) {
byte[] bytes = new byte[keyLength];
this.random.nextBytes(bytes);
return bytes;
}
一旦你生成了盐,你可以使用下面的代码来对给定的内容进行编码。
var cpuCost = 65536;
var memoryCost = 8;
var parallelization = 1;
var keyLength = 32;
var saltLength = 16;
var rawPassword = "abcdef";
var salt = generateKey(saltLength);
byte[] derived = SCrypt.generate(Utf8.encode(rawPassword), salt, cpuCost, memoryCost, parallelization, keyLength);
String params = Long.toString( ((int) (Math.log(cpuCost) / Math.log(2)) << 16L) | memoryCost << 8 | parallelization, 16);
StringBuilder sb = new StringBuilder((salt.length + derived.length) * 2);
sb.append("$").append(params).append('$');
sb.append(encodePart(salt)).append('$');
sb.append(encodePart(derived));
val encodedValue = sb.toString();
Scrypt也被用于Spring Security中的密码编码,所以如果你已经在使用Spring,你可以简单地使用
SCryptPasswordEncoder
进行编码和匹配。
这个类提供了静态工厂方法,专为Spring使用进行了优化,例如:
SCryptPasswordEncoder scryptEncoder = SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8();
String hashedValue = scryptEncoder.encode("abcdef");
//To match the encoded string with raw value
boolean isSame = scryptEncoder.matches("abcdef", hashedValue);
希望能对你有所帮助!
Scrypt
类?你只需要import org.bouncycastle.crypto.generators.SCrypt
,然后使用generate
方法:SCrypt.generate(parameters...)
。确保在它们的网站上下载bouncycastle jars(或者如果你正在使用maven,则包含在你的pom.xml
中)。 - user7605325