我真的一直在努力尝试让 Bouncy Castle Scrypt 在我的网络应用程序中进行密码加密。我对 Java 编程和安全性相当陌生。
我尝试查看 Bouncy Castle 的 Scrypt 类文档。然而,我很难弄清楚它是如何工作的。它似乎并没有真正提供有关如何创建类或类似内容的太多信息。
我在 Stack Exchange 和 Google 上进行了搜索,看看是否有任何地方可以给我一个很好的例子,告诉我应该如何创建这个类。我找到了这个问题和答案,并且我在没有创建类的情况下尝试了它,但这似乎也不起作用。
最重要的是,我的导入似乎也不起作用。
这是我拥有的所有代码:
import org.bouncycastle.crypto.generators;
public class SCrypt extends java.lang.Object {
public Scrypt(){}
public static byte[] generate(byte[] P,byte[] S,int N,int r,int p,int dkLen) {
}
}
我想使用 Scrypt,因为它似乎是加密密码最安全的方法,但它似乎不太可能实现。我非常接近使用 PBKDF2,因为有更多关于它的文档,但我希望有人可以帮助我实现这一目标。
感谢雨果的反馈! 经过一番努力和搜索,我找到了这个网站:http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse- for-java-jse-项目/
这帮助我逐步了解了在我的计算机上安装和运行 Bouncy Castle 所需的内容。 我希望这会对其他人有所帮助,因为我花了很长时间才找到将其分解为外行术语的东西。 :)
Scrypt 哈希算法广泛用于基于 Java 的应用程序(因为 MD5 和其他 JDK 附带的算法被认为很容易破解)。
JDK不为Scrypt提供SPI,因此您需要为Scrypt使用BouncyCastle提供程序。您可以在项目中使用以下依赖项:
org.bouncycastle:bcprov-jdk18on:1.76
您可以根据您的Java版本使用合适的版本。
现在,您需要决定或生成以下参数来定义 Scrypt 哈希的复杂性:
cpuCost
(int): 定义cpu成本,必须大于1且小于
大于等于 65536memoryCost
(int): 定义内存消耗,必须更大
超过 1parallelization
(int):定义并行化,必须是
大于 1 且小于 Integer.MAX_VALUE / (128 * memoryCost * 8)
keyLength
(int):密钥长度必须大于1salt
(int):盐长度必须大于 1现在您可以在给定盐大小的字节数组中生成盐,如下所示:
SecureRandom random = new SecureRandom();
public byte[] generateKey(int keyLength) {
byte[] bytes = new byte[keyLength];
this.random.nextBytes(bytes);
return bytes;
}
生成 Salt 后,您可以使用下面的代码对给定的进行编码
var cpuCost = 65536;
var memoryCost = 8;
var parallelization = 1;
var keyLength = 32;
var saltLength = 16;
var rawPassword = "abcdef"; //String to be hashed
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);
希望对您有帮助!