Reputation: 479
I have really been struggling trying to get Bouncy Castle Scrypt going in my web app for password encryption. I am fairly new to programming in Java and security.
I have tried looking at Bouncy Castle's documentation for their Scrypt class. However, I have a really hard time trying to figure out how it works. It doesn't seem to really give much information as to how to create the class or anything like that.
I searched around Stack Exchange and Google to see if there is anywhere that could give me a good example as to what I should do to create this class. I found this question and answer, and I tried it out without creating a class, but that didn't seem to work either.
To top this off, my import doesn't seem to want to work either.
This is all of the code that I have:
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) {
}
}
I want to use Scrypt since it seems to be the most secure in encrypting passwords, but it seems next impossible to implement. I'm really close with just going with a PBKDF2 since there is more documentation on it, but I'm hoping that there is someone out there who can help me get this going.
Upvotes: 3
Views: 6761
Reputation: 682
The Scrypt hashing algorithm is widely used in Java based application (as MD5 and other JDK shipped algorithms are considered easy to break).
The JDK does not provide SPI for Scrypt so you need to use BouncyCastle provider for Scrypt. You can use below dependency in your project:
org.bouncycastle:bcprov-jdk18on:1.76
You can use appropriate version as per your Java version.
Now, you need to decide or generate below parameters to define the complexity of for your Scrypt hashing:
cpuCost
(int): Define the cpu cost, must be greater than 1 and less
than equal to 65536memoryCost
(int): Define memory cost, must be greater
than 1parallelization
(int): Define parallelization, must be
greater than 1 and less than Integer.MAX_VALUE / (128 * memoryCost * 8)
keyLength
(int): Key length must be greater than 1salt
(int): Salt length must be greater than 1Now you can generate salt in byte array of given salt size as:
SecureRandom random = new SecureRandom();
public byte[] generateKey(int keyLength) {
byte[] bytes = new byte[keyLength];
this.random.nextBytes(bytes);
return bytes;
}
Once you generate Salt then you can use below code to encode the given
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 is also used in Spring Security for Password encoding, so if you are already using Spring then you can simple use SCryptPasswordEncoder
to encode and match.
This class provide static factory method which is optimized for Spring use like:
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);
Hope it will help you!
Upvotes: 0
Reputation: 479
Thanks Hugo for the feedback! After much struggle and searching, I found this website: http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/
This helped give me a breakdown step-by-step on what I needed to get Bouncy Castle up and running on my computer. I hope this will help others since I struggled with it for so long to find something that broke this down into layman's terms. :)
Upvotes: 2