forked from sergeych/crypto2
0.5.7 better KDF complexity levels
This commit is contained in:
parent
b975df9a13
commit
491f9d47f6
@ -19,7 +19,7 @@ repositories {
|
|||||||
maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven")
|
maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven")
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
import("net.sergeych:crypto2:0.5.6")
|
import("net.sergeych:crypto2:0.5.7")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
version = "0.5.6"
|
version = "0.5.7"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -4,25 +4,39 @@ import com.ionspin.kotlin.crypto.pwhash.*
|
|||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import net.sergeych.bipack.Unsigned
|
import net.sergeych.bipack.Unsigned
|
||||||
|
import net.sergeych.crypto2.KDF.Argon.Alg.V2id_13
|
||||||
|
import net.sergeych.crypto2.KDF.Complexity.*
|
||||||
import net.sergeych.crypto2.PBKD.Params
|
import net.sergeych.crypto2.PBKD.Params
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
sealed class KDF {
|
sealed class KDF {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KDF complexity: how many resources (CPY and RAM) it requires to transform a string to a key.
|
||||||
|
*
|
||||||
|
* Constants started with `Fixed...`, e.g., [FixedLow], [FixedMedium] and [FixedHigher]
|
||||||
|
* are first clas constants not to be changed in future but can become obsolete (too simple) with the
|
||||||
|
* development of the computer hardware. Other constants can change in future releases, so it is critical
|
||||||
|
* to serialize [KDF] or [PBKD.Params] generated with such constants and restore them before
|
||||||
|
* deriving keys.
|
||||||
|
*/
|
||||||
enum class Complexity {
|
enum class Complexity {
|
||||||
|
FixedLow,
|
||||||
Interactive,
|
Interactive,
|
||||||
|
FixedMedium,
|
||||||
Moderate,
|
Moderate,
|
||||||
|
FixedHigher,
|
||||||
Sensitive,
|
Sensitive,
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun derive(password: String): UByteArray
|
abstract fun derive(password: String): UByteArray
|
||||||
|
|
||||||
fun deriveMultiple(password: String,count: Int) : List<SymmetricKey> {
|
fun deriveMultiple(password: String, count: Int): List<SymmetricKey> {
|
||||||
val bytes = derive(password)
|
val bytes = derive(password)
|
||||||
val ks = SymmetricKey.keyLength
|
val ks = SymmetricKey.keyLength
|
||||||
check( ks * count <= bytes.size ) { "KDF is too short for $count keys: ${bytes.size} we need ${ks*count}"}
|
check(ks * count <= bytes.size) { "KDF is too short for $count keys: ${bytes.size} we need ${ks * count}" }
|
||||||
return (0 ..< count).map {
|
return (0..<count).map {
|
||||||
val base = it*ks
|
val base = it * ks
|
||||||
Params(this, base, ks).deriveKey(password)
|
Params(this, base, ks).deriveKey(password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,6 +71,7 @@ sealed class KDF {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class Alg(val code: Int) {
|
enum class Alg(val code: Int) {
|
||||||
|
@Suppress("EnumEntryName", "unused")
|
||||||
V2i_13(crypto_pwhash_argon2i_ALG_ARGON2I13),
|
V2i_13(crypto_pwhash_argon2i_ALG_ARGON2I13),
|
||||||
V2id_13(crypto_pwhash_argon2id_ALG_ARGON2ID13),
|
V2id_13(crypto_pwhash_argon2id_ALG_ARGON2ID13),
|
||||||
;
|
;
|
||||||
@ -100,14 +115,27 @@ sealed class KDF {
|
|||||||
require(salt.size == saltSize) { "The salt size should be $saltSize" }
|
require(salt.size == saltSize) { "The salt size should be $saltSize" }
|
||||||
require(keySize > minKeySize) { "The key size should be at least $keySize bytes" }
|
require(keySize > minKeySize) { "The key size should be at least $keySize bytes" }
|
||||||
return when (complexity) {
|
return when (complexity) {
|
||||||
Complexity.Interactive -> Argon(
|
FixedLow -> Argon(
|
||||||
|
V2id_13,
|
||||||
|
2UL,
|
||||||
|
67108864,
|
||||||
|
salt, keySize
|
||||||
|
)
|
||||||
|
|
||||||
|
Interactive -> Argon(
|
||||||
Alg.default,
|
Alg.default,
|
||||||
crypto_pwhash_OPSLIMIT_INTERACTIVE.toULong(),
|
crypto_pwhash_OPSLIMIT_INTERACTIVE.toULong(),
|
||||||
crypto_pwhash_MEMLIMIT_INTERACTIVE,
|
crypto_pwhash_MEMLIMIT_INTERACTIVE,
|
||||||
salt, keySize
|
salt, keySize
|
||||||
)
|
)
|
||||||
|
|
||||||
Complexity.Moderate -> Argon(
|
FixedMedium -> Argon(
|
||||||
|
V2id_13,
|
||||||
|
3UL,
|
||||||
|
268435456,
|
||||||
|
salt, keySize
|
||||||
|
)
|
||||||
|
Moderate -> Argon(
|
||||||
Alg.default,
|
Alg.default,
|
||||||
crypto_pwhash_OPSLIMIT_MODERATE,
|
crypto_pwhash_OPSLIMIT_MODERATE,
|
||||||
crypto_pwhash_MEMLIMIT_MODERATE,
|
crypto_pwhash_MEMLIMIT_MODERATE,
|
||||||
@ -120,6 +148,14 @@ sealed class KDF {
|
|||||||
crypto_pwhash_MEMLIMIT_SENSITIVE,
|
crypto_pwhash_MEMLIMIT_SENSITIVE,
|
||||||
salt, keySize
|
salt, keySize
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Complexity.FixedHigher -> Argon(
|
||||||
|
V2id_13,
|
||||||
|
4UL,
|
||||||
|
1073741824,
|
||||||
|
salt, keySize
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,11 +164,11 @@ sealed class KDF {
|
|||||||
companion object {
|
companion object {
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun creteDefault(keySize: Int, complexity: Complexity, salt: UByteArray = Argon.randomSalt()): KDF {
|
fun creteDefault(keySize: Int, complexity: Complexity, salt: UByteArray = Argon.randomSalt()): KDF {
|
||||||
return Argon.create(complexity,salt,keySize)
|
return Argon.create(complexity, salt, keySize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Instance(val kdf: KDF,val password: String)
|
data class Instance(val kdf: KDF, val password: String)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user