Perdue
Perdue

Reputation: 479

How to implement Scrypt in Java?

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

Answers (2)

Sandeep Kumar
Sandeep Kumar

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 65536
  • memoryCost (int): Define memory cost, must be greater than 1
  • parallelization (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 1
  • salt (int): Salt length must be greater than 1

Now 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

Perdue
Perdue

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

Related Questions