-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1499 from digitalfabrik/1433-create-argon2-user-h…
…ashing-for-koblenz 1433: Create user hashing for Koblenz
- Loading branch information
Showing
16 changed files
with
364 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
backend/src/main/kotlin/app/ehrenamtskarte/backend/cards/Argon2IdHasher.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
|
||
import app.ehrenamtskarte.backend.cards.CanonicalJson | ||
import app.ehrenamtskarte.backend.common.utils.Environment | ||
import app.ehrenamtskarte.backend.common.webservice.KOBLENZ_PEPPER_SYS_ENV | ||
import app.ehrenamtskarte.backend.userdata.KoblenzUser | ||
import org.bouncycastle.crypto.generators.Argon2BytesGenerator | ||
import org.bouncycastle.crypto.params.Argon2Parameters | ||
import java.nio.charset.StandardCharsets | ||
import java.util.Base64 | ||
|
||
class Argon2IdHasher { | ||
companion object { | ||
/** | ||
* Copied from spring-security Argon2EncodingUtils.java licenced under Apache 2.0, removed the salt from the result | ||
* | ||
* Encodes a raw Argon2-hash and its parameters into the standard Argon2-hash-string | ||
* as specified in the reference implementation | ||
* (https://github.com/P-H-C/phc-winner-argon2/blob/master/src/encoding.c#L244): | ||
* | ||
* {@code $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>$<bin>$<bin>} | ||
**/ | ||
@Throws(IllegalArgumentException::class) | ||
private fun encodeWithoutSalt( | ||
hash: ByteArray?, | ||
parameters: Argon2Parameters | ||
): String? { | ||
val b64encoder: Base64.Encoder = Base64.getEncoder().withoutPadding() | ||
val stringBuilder = StringBuilder() | ||
val type = | ||
when (parameters.type) { | ||
Argon2Parameters.ARGON2_d -> "\$argon2d" | ||
Argon2Parameters.ARGON2_i -> "\$argon2i" | ||
Argon2Parameters.ARGON2_id -> "\$argon2id" | ||
else -> throw IllegalArgumentException("Invalid algorithm type: " + parameters.type) | ||
} | ||
stringBuilder.append(type) | ||
stringBuilder | ||
.append("\$v=") | ||
.append(parameters.version) | ||
.append("\$m=") | ||
.append(parameters.memory) | ||
.append(",t=") | ||
.append(parameters.iterations) | ||
.append(",p=") | ||
.append(parameters.lanes) | ||
stringBuilder.append("$").append(b64encoder.encodeToString(hash)) | ||
return stringBuilder.toString() | ||
} | ||
|
||
fun hashKoblenzUserData(userData: KoblenzUser): String? { | ||
val canonicalJson = CanonicalJson.koblenzUserToString(userData) | ||
val hashLength = 32 | ||
|
||
val pepper = Environment.getVariable(KOBLENZ_PEPPER_SYS_ENV) ?: throw Exception("No koblenz pepper found") | ||
val pepperByteArray = pepper.toByteArray(StandardCharsets.UTF_8) | ||
val params = | ||
Argon2Parameters | ||
.Builder(Argon2Parameters.ARGON2_id) | ||
.withVersion(19) | ||
.withIterations(2) | ||
.withSalt(pepperByteArray) | ||
.withParallelism(1) | ||
.withMemoryAsKB(19456) | ||
.build() | ||
|
||
val generator = Argon2BytesGenerator() | ||
generator.init(params) | ||
val result = ByteArray(hashLength) | ||
generator.generateBytes(canonicalJson.toByteArray(), result) | ||
return encodeWithoutSalt(result, params) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
backend/src/main/kotlin/app/ehrenamtskarte/backend/common/utils/Environment.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package app.ehrenamtskarte.backend.common.utils | ||
|
||
// This helper class was created to enable mocking getenv in Tests | ||
class Environment { | ||
companion object { | ||
fun getVariable(name: String): String? = System.getenv(name) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
...c/main/kotlin/app/ehrenamtskarte/backend/exception/service/NotCorrectProjectExceptions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
package app.ehrenamtskarte.backend.exception.service | ||
|
||
class NotEakProjectException() : Exception("This query can only be used for EAK project") | ||
|
||
class NotKoblenzProjectException() : Exception("This query can only be used for Koblenz project") |
4 changes: 0 additions & 4 deletions
4
...nd/src/main/kotlin/app/ehrenamtskarte/backend/exception/service/NotEakProjectException.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
backend/src/main/kotlin/app/ehrenamtskarte/backend/userdata/KoblenzUser.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package app.ehrenamtskarte.backend.userdata | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty | ||
import com.fasterxml.jackson.annotation.JsonPropertyOrder | ||
|
||
@JsonPropertyOrder(alphabetic = true) | ||
data class KoblenzUser(@get:JsonProperty("1") val fullname: String, @get:JsonProperty("2") val birthday: Int, @get:JsonProperty("3") val referenceNumber: String) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
backend/src/test/kotlin/app/ehrenamtskarte/backend/cards/Argon2IdHasherTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package app.ehrenamtskarte.backend.verification | ||
import Argon2IdHasher | ||
import app.ehrenamtskarte.backend.common.utils.Environment | ||
import app.ehrenamtskarte.backend.common.webservice.KOBLENZ_PEPPER_SYS_ENV | ||
import app.ehrenamtskarte.backend.userdata.KoblenzUser | ||
import io.mockk.every | ||
import io.mockk.mockkObject | ||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
|
||
internal class Argon2IdHasherTest { | ||
@Test | ||
fun isHashingCorrectly() { | ||
mockkObject(Environment) | ||
every { Environment.getVariable(KOBLENZ_PEPPER_SYS_ENV) } returns "123456789ABC" | ||
|
||
assertEquals(Environment.getVariable("KOBLENZ_PEPPER"), "123456789ABC") | ||
|
||
val hash = Argon2IdHasher.hashKoblenzUserData(KoblenzUser("Karla Koblenz", 12213, "123K")) | ||
val expectedHash = "\$argon2id\$v=19\$m=19456,t=2,p=1\$57YPIKvU/XE9h7/JA0tZFT2TzpwBQfYAW6K+ojXBh5w" // This expected output was created with https://argon2.online/ | ||
assertEquals(expectedHash, hash) | ||
} | ||
} |
Oops, something went wrong.