1
1
package stroom .receive .common ;
2
2
3
- import stroom .util .string .Base58 ;
3
+ import stroom .util .string .StringUtil ;
4
4
5
+ import org .apache .commons .codec .binary .Hex ;
5
6
import org .bouncycastle .crypto .generators .Argon2BytesGenerator ;
6
7
import org .bouncycastle .crypto .params .Argon2Parameters ;
7
8
import org .bouncycastle .crypto .params .Argon2Parameters .Builder ;
8
9
9
10
import java .nio .charset .StandardCharsets ;
11
+ import java .security .SecureRandom ;
10
12
import java .util .Objects ;
11
13
12
14
class Argon2DataFeedKeyHasher implements DataFeedKeyHasher {
@@ -20,23 +22,33 @@ class Argon2DataFeedKeyHasher implements DataFeedKeyHasher {
20
22
private static final int MEMORY_KB = 65_536 ;
21
23
private static final int PARALLELISM = 1 ;
22
24
23
- private final Argon2Parameters argon2Parameters ;
25
+ private final SecureRandom secureRandom ;
24
26
25
27
public Argon2DataFeedKeyHasher () {
26
- // No salt given the length of api keys being hashed
27
- this .argon2Parameters = new Builder (Argon2Parameters .ARGON2_id )
28
+ this .secureRandom = new SecureRandom ();
29
+ }
30
+
31
+ @ Override
32
+ public HashOutput hash (final String dataFeedKey ) {
33
+ final String randomSalt = StringUtil .createRandomCode (
34
+ secureRandom ,
35
+ 32 ,
36
+ StringUtil .ALLOWED_CHARS_BASE_58_STYLE );
37
+ return hash (dataFeedKey , randomSalt );
38
+ }
39
+
40
+ public HashOutput hash (final String dataFeedKey , final String salt ) {
41
+ final Argon2Parameters params = new Builder (Argon2Parameters .ARGON2_id )
28
42
.withVersion (Argon2Parameters .ARGON2_VERSION_13 )
29
43
.withIterations (ITERATIONS )
30
44
.withMemoryAsKB (MEMORY_KB )
31
45
.withParallelism (PARALLELISM )
46
+ .withSalt (salt .getBytes (StandardCharsets .UTF_8 ))
32
47
.build ();
33
- }
34
48
35
- @ Override
36
- public String hash (final String dataFeedKey ) {
37
49
Objects .requireNonNull (dataFeedKey );
38
- Argon2BytesGenerator generator = new Argon2BytesGenerator ();
39
- generator .init (argon2Parameters );
50
+ final Argon2BytesGenerator generator = new Argon2BytesGenerator ();
51
+ generator .init (params );
40
52
byte [] result = new byte [HASH_LENGTH ];
41
53
generator .generateBytes (
42
54
dataFeedKey .trim ().getBytes (StandardCharsets .UTF_8 ),
@@ -46,7 +58,16 @@ public String hash(final String dataFeedKey) {
46
58
47
59
// Base58 is a bit less nasty than base64 and widely supported in other languages
48
60
// due to use in bitcoin.
49
- return Base58 .encode (result );
61
+ final String hash = Hex .encodeHexString (result );
62
+ return new HashOutput (hash , salt );
63
+ }
64
+
65
+ @ Override
66
+ public boolean verify (final String dataFeedKey , final String hash , final String salt ) {
67
+ Objects .requireNonNull (dataFeedKey );
68
+ Objects .requireNonNull (hash );
69
+ final HashOutput hashOutput = hash (dataFeedKey , salt );
70
+ return Objects .equals (hash , hashOutput .hash ());
50
71
}
51
72
52
73
@ Override
0 commit comments