PBKD semi ready, before key refactoring
This commit is contained in:
parent
2cd4eaccab
commit
5c97e857fc
@ -2,7 +2,6 @@ package net.sergeych.crypto2
|
||||
|
||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import net.sergeych.bipack.BipackEncoder
|
||||
import net.sergeych.bipack.Unsigned
|
||||
import net.sergeych.synctools.ProtectedOp
|
||||
@ -10,17 +9,31 @@ import net.sergeych.synctools.invoke
|
||||
|
||||
object PBKD {
|
||||
|
||||
/**
|
||||
* Parameters to generate a reasonably secure data bytes with [deriveUBytes] or a [SymmetricKey]
|
||||
* with [deriveKey]
|
||||
*/
|
||||
@Serializable
|
||||
class Params(
|
||||
val kdf: KDF,
|
||||
@Unsigned
|
||||
val startOffset: Int,
|
||||
@Transient
|
||||
private var precalculatedKey: SymmetricKey?=null
|
||||
@Unsigned
|
||||
val length: Int,
|
||||
) {
|
||||
|
||||
/**
|
||||
* Derive a key from the password in the idempotent manner.
|
||||
* Derive UByteArray from the password in the idempotent way.
|
||||
* Could be used to construct keys, IVs, tokens, whatever.
|
||||
* Most often [deriveKey] is used instead which derives the key.
|
||||
*/
|
||||
fun deriveUBytes(password: String): UByteArray {
|
||||
val bytes = generate(kdf, password)
|
||||
return bytes.sliceArray(startOffset..<startOffset + length)
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a new key from the password in the idempotent manner.
|
||||
* If the [keyId] is provided, it will be used to determine key type (otherwise default asymmetric)
|
||||
* and to check the result, and the exception will be thrown.
|
||||
*
|
||||
@ -31,10 +44,7 @@ object PBKD {
|
||||
* @param keyId optional key id, to get a key type from and check the result
|
||||
* @throws IncorrectPasswordException if [keyId] is provided and does not match the derivation result
|
||||
*/
|
||||
fun derive(password: String, keyId: KeyId? = null): SymmetricKey {
|
||||
// could be already calculated
|
||||
precalculatedKey?.let { return it }
|
||||
|
||||
fun deriveKey(password: String, keyId: KeyId? = null): SymmetricKey {
|
||||
// check key id sanity
|
||||
keyId?.let {
|
||||
if (it.id.magick != KeysMagickNumber.defaultSymmetric.number) {
|
||||
@ -42,28 +52,36 @@ object PBKD {
|
||||
}
|
||||
}
|
||||
// this will not be ok when we support other key types:
|
||||
val keySize = SymmetricKey.keyLength
|
||||
if (SymmetricKey.keyLength != length)
|
||||
throw NotSupportedException("can't create key from $length byte(s), required ${SymmetricKey.keyLength}")
|
||||
|
||||
// derive
|
||||
val bytes = generate(kdf, password)
|
||||
val key = SymmetricKey(bytes.sliceArray(startOffset..<startOffset + keySize), this)
|
||||
val key = SymmetricKey(
|
||||
deriveUBytes(password)
|
||||
.sliceArray(startOffset..<startOffset + SymmetricKey.keyLength),
|
||||
this
|
||||
)
|
||||
|
||||
// check if we can checking
|
||||
if( keyId != null && keyId != key.id )
|
||||
// check if we can
|
||||
if (keyId != null && keyId != key.id)
|
||||
throw IncorrectPasswordException()
|
||||
|
||||
// save for later
|
||||
precalculatedKey = key
|
||||
|
||||
return key
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create [PBKD.Params] to derive several keys from the single password
|
||||
* Derive several keys-suitable params
|
||||
*/
|
||||
fun createMutlipleParams(complexity: KDF.Complexity,keysCount: Int): List<Params> {
|
||||
TODO()
|
||||
fun deriveMultipleKeys(password: String,keysCount: Int,
|
||||
complexity: KDF.Complexity = KDF.Complexity.Moderate,
|
||||
salt: UByteArray = KDF.Argon.randomSalt()
|
||||
): List<SymmetricKey> {
|
||||
require(keysCount > 0) { "keysCount must be positive" }
|
||||
val keyLength = SymmetricKey.keyLength
|
||||
val totalSize = keysCount * keyLength
|
||||
val kdf = KDF.Argon.create(complexity, salt, totalSize)
|
||||
return (0 ..< keysCount).map { Params(kdf, it*keyLength, keyLength).deriveKey(password) }
|
||||
}
|
||||
|
||||
private val op = ProtectedOp()
|
||||
|
@ -55,10 +55,8 @@ sealed class KDF {
|
||||
}
|
||||
}
|
||||
|
||||
override fun derive(password: String): UByteArray {
|
||||
TODO()
|
||||
//PasswordHash.pwhash(keySize, )
|
||||
}
|
||||
override fun derive(password: String): UByteArray =
|
||||
PasswordHash.pwhash(keySize, password, salt, instructionsComplexity, memComplexity, algorithm.code)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
Loading…
x
Reference in New Issue
Block a user