at.gadermaier.argon2.Argon2 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of LockLogin Show documentation
Show all versions of LockLogin Show documentation
Adds an extra protection to your Bukkit-Spigot-Paper/BungeeCord server with this plugins that adds 2FA to his security system
The newest version!
package at.gadermaier.argon2;
import at.gadermaier.argon2.algorithm.FillMemory;
import at.gadermaier.argon2.algorithm.Finalize;
import at.gadermaier.argon2.algorithm.Initialize;
import at.gadermaier.argon2.model.Argon2Type;
import at.gadermaier.argon2.model.Instance;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static at.gadermaier.argon2.Constants.Defaults.*;
import static at.gadermaier.argon2.Util.clearArray;
import static at.gadermaier.argon2.Util.toByteArray;
import static at.gadermaier.argon2.model.Argon2Type.*;
public class Argon2 {
private byte[] output;
private int outputLength; // -l N
private byte[] password;
private byte[] salt;
private byte[] secret;
private byte[] additional;
private int iterations; // -t N
private int memory; // -m N
private int lanes; // -p N
private int version; // -v (10/13)
private Argon2Type type;
private boolean clearMemory = true;
private ExecutorService executor;
private static final class ExecutorHolder {
private static final ExecutorService executor = Executors.newCachedThreadPool();
}
private Argon2() {
this.lanes = LANES_DEF;
this.outputLength = OUTLEN_DEF;
this.memory = 1 << LOG_M_COST_DEF;
this.iterations = T_COST_DEF;
this.version = VERSION_DEF;
this.type = TYPE_DEF;
}
public static Argon2 create() {
return new Argon2();
}
private static Argon2 createFromEncoded( String encoded ) {
String[] parts = encoded.split( "\\$" );
Argon2Type type = parts[1].endsWith( "id" ) ? Argon2id :
parts[1].endsWith( "i" ) ? Argon2i :
parts[1].endsWith( "d" ) ? Argon2d : null;
boolean hasVersion = !parts[2].startsWith( "m=" );
String version = hasVersion ? parts[2].split( "=" )[1] : "16";
String[] paramParts = ( hasVersion ? parts[3] : parts[2] ).split( "," );
String m = paramParts[0].split( "=" )[1];
String t = paramParts[1].split( "=" )[1];
String p = paramParts[2].split( "=" )[1];
String saltEncoded = hasVersion ? parts[4] : parts[3];
byte[] salt = Base64.getDecoder().decode( saltEncoded );
String hashEncoded = hasVersion ? parts[5] : parts[4];
byte[] hash = Base64.getDecoder().decode( hashEncoded );
Argon2 instance = new Argon2();
instance.type( type );
instance.version( Integer.parseInt( version ) );
instance.memoryKB( Integer.parseInt( m ) );
instance.iterations( Integer.parseInt( t ) );
instance.parallelism( Integer.parseInt( p ) );
instance.salt( salt );
instance.setOutput( hash );
return instance;
}
public static boolean checkHash( String encoded, byte[] password ) {
Argon2 argon2 = Argon2.createFromEncoded( encoded );
byte[] expectedHash = Arrays.copyOf( argon2.getOutput(), argon2.getOutput().length );
argon2.password( password );
Argon2Result result = argon2.hash();
return Arrays.equals( result.asByte(), expectedHash );
}
public static boolean checkHash( String encoded, String password ) {
return checkHash( encoded, password.getBytes( StandardCharsets.UTF_8 ) );
}
public static boolean checkHash( String encoded, String password, Charset charset ) {
return checkHash( encoded, password.getBytes( charset ) );
}
public Argon2Result hash( byte[] password, byte[] salt ) {
password( password );
salt( salt );
return hash();
}
public Argon2Result hash( char[] password, String salt, Charset charset ) {
password( toByteArray( password, charset ) );
salt( salt.getBytes( charset ) );
return hash();
}
public Argon2Result hash( String password, String salt ) {
return hash( password, salt, StandardCharsets.UTF_8 );
}
public Argon2Result hash( String password, String salt, Charset charset ) {
password( password.getBytes( charset ) );
salt( salt.getBytes( charset ) );
return hash();
}
public Argon2Result hash() {
try {
byte[] keepSalt = Arrays.copyOf(salt, salt.length );
argon2_hash();
return new Argon2Result( type, version, memory, iterations, lanes, keepSalt, output );
} finally {
clear();
}
}
private void argon2_hash() {
if ( executor == null ) {
executor = ExecutorHolder.executor;
}
Validation.validateInput( this );
Instance instance = new Instance( this );
Initialize.initialize( instance, this );
FillMemory.fillMemoryBlocks( instance, executor );
Finalize.finalize( instance, this );
}
public void clear() {
clearArray( password );
clearArray( salt );
clearArray( secret );
clearArray( additional );
}
public Argon2 memoryKB(int memory ) {
this.memory = memory;
return this;
}
public Argon2 parallelism(int parallelism ) {
this.lanes = parallelism;
return this;
}
public byte[] getOutput() {
return output;
}
public void setOutput( byte[] finalResult ) {
this.output = finalResult;
}
public String getOutputString() {
return Util.bytesToHexString( output );
}
public int getOutputLength() {
return outputLength;
}
public Argon2 output(int outputLength ) {
this.outputLength = outputLength;
return this;
}
public byte[] getPassword() {
return password;
}
public Argon2 password(byte[] password ) {
this.password = password;
return this;
}
public int getPasswordLength() {
return password.length;
}
public byte[] getSalt() {
return salt;
}
public Argon2 salt(byte[] salt ) {
this.salt = salt;
return this;
}
public int getSaltLength() {
return salt.length;
}
public byte[] getSecret() {
return secret;
}
public Argon2 secret(byte[] secret ) {
this.secret = secret;
return this;
}
public int getSecretLength() {
return secret != null ? secret.length : 0;
}
public byte[] getAdditional() {
return additional;
}
public Argon2 additional(byte[] additional ) {
this.additional = additional;
return this;
}
public int getAdditionalLength() {
return additional != null ? additional.length : 0;
}
public int getIterations() {
return iterations;
}
public Argon2 iterations(int iterations ) {
this.iterations = iterations;
return this;
}
public int getMemory() {
return memory;
}
public Argon2 memory(int memory ) {
this.memory = 1 << memory;
return this;
}
public int getLanes() {
return lanes;
}
public int getVersion() {
return version;
}
public Argon2 version(int version ) {
this.version = version;
return this;
}
public Argon2Type getType() {
return type;
}
public Argon2 type(Argon2Type type ) {
this.type = type;
return this;
}
public boolean isClearMemory() {
return clearMemory;
}
public void setClearMemory( boolean clearMemory ) {
this.clearMemory = clearMemory;
}
public Executor getExecutor() {
return executor;
}
public Argon2 executor(ExecutorService executor ) {
this.executor = executor;
return this;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy