extending to be more convenient
This commit is contained in:
parent
640ceb448e
commit
9f7babdf58
@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "net.sergeych"
|
||||
version = "0.6.1-SNAPSHOT"
|
||||
version = "0.6.2-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -60,6 +60,8 @@ class ByteChunk(val data: UByteArray): Comparable<ByteChunk> {
|
||||
*/
|
||||
val hex by lazy { data.encodeToHex() }
|
||||
|
||||
val base64Url by lazy { data.encodeToBase64Url() }
|
||||
|
||||
/**
|
||||
* human-readable dump
|
||||
*/
|
||||
@ -75,9 +77,14 @@ class ByteChunk(val data: UByteArray): Comparable<ByteChunk> {
|
||||
|
||||
companion object {
|
||||
fun fromHex(hex: String): ByteChunk = ByteChunk(hex.decodeHex().asUByteArray())
|
||||
fun random(sizeInBytes: Int=16) = randomUBytes(sizeInBytes).toChunk()
|
||||
}
|
||||
}
|
||||
|
||||
private fun UByteArray.toChunk(): ByteChunk = ByteChunk(this)
|
||||
@Suppress("unused")
|
||||
private fun ByteArray.toChunk(): ByteChunk = ByteChunk(this.asUByteArray())
|
||||
|
||||
@Suppress("unused")
|
||||
fun ByteArray.asChunk() = ByteChunk(toUByteArray())
|
||||
fun UByteArray.asChunk(): ByteChunk = ByteChunk(this)
|
@ -155,6 +155,11 @@ sealed class Container {
|
||||
var authorisedByKey: PublicKey? = null
|
||||
protected set
|
||||
|
||||
/**
|
||||
* List of [KeyId] of the keys that unlocked the container, in the same order used for encryption..
|
||||
*/
|
||||
abstract val keyIds: List<KeyId>
|
||||
|
||||
|
||||
/**
|
||||
* @suppress
|
||||
@ -175,6 +180,8 @@ sealed class Container {
|
||||
override val decryptedWithKeyId: KeyId?
|
||||
get() = decryptedWithKey?.id
|
||||
|
||||
override val keyIds: List<KeyId> = listOf(keyId)
|
||||
|
||||
init {
|
||||
decryptedData = creationData
|
||||
}
|
||||
@ -270,6 +277,8 @@ sealed class Container {
|
||||
override var decryptedWithKeyId: KeyId? = null
|
||||
private set
|
||||
|
||||
override val keyIds: List<KeyId> = encryptedKeys.map { it.tag }
|
||||
|
||||
override fun decryptWith(keyRing: UniversalRing): UByteArray? {
|
||||
decryptedData?.let { return it }
|
||||
for (key in keyRing.decryptingKeys) {
|
||||
|
@ -46,7 +46,7 @@ class SymmetricKey(
|
||||
override val nonceBytesLength: Int = nonceLength
|
||||
|
||||
override val id by lazy {
|
||||
KeyId(KeysmagicNumber.defaultSymmetric,blake2b3l(keyBytes), pbkdfParams)
|
||||
KeyId(KeysmagicNumber.defaultSymmetric,blake2b3l(keyBytes),pbkdfParams)
|
||||
}
|
||||
|
||||
override fun decryptWithNonce(cipherData: UByteArray, nonce: UByteArray): UByteArray =
|
||||
|
@ -27,10 +27,40 @@ sealed class KDF {
|
||||
Moderate,
|
||||
FixedHigher,
|
||||
Sensitive,
|
||||
;
|
||||
|
||||
/**
|
||||
* Create [KDF] of the corresponding strength suitable to derive [numberOfKeys] symmetric keys.
|
||||
*
|
||||
* Random salt of proper size is used
|
||||
*/
|
||||
fun kdfForSize(numberOfKeys: Int): KDF = creteDefault(SymmetricKey.keyLength*numberOfKeys, this)
|
||||
|
||||
/**
|
||||
* Derive multiple keys from the password. Derivation params will be included in the key ids, see
|
||||
* [SymmetricKey.id] as [KeyId.kdp].
|
||||
|
||||
* Random salt of proper size is used
|
||||
*
|
||||
* ___Important: symmetric keys do not save key ids___. _Container do it, so it is possible to re-derive
|
||||
* key to open the container, but in many cases you might need to save [KeyId.kdp] separately_.
|
||||
* Having no [PBKD.Params] it would not be possible to recreate the key, as complexity defaults tend
|
||||
* to change with time.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun deriveMultiple(password: String, count: Int): List<SymmetricKey> =
|
||||
kdfForSize(count).deriveMultiple(password, count)
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a single key from the password, same as [deriveMultiple] with `count==1`
|
||||
*/
|
||||
abstract fun derive(password: String): UByteArray
|
||||
|
||||
/**
|
||||
* Derive keys from lower part of bytes derived from the password. E.g., if generated size is longer than
|
||||
* required to create [count] keys, the first bytes will be used. It let use rest bytes for other purposes.
|
||||
*/
|
||||
fun deriveMultiple(password: String, count: Int): List<SymmetricKey> {
|
||||
val bytes = derive(password)
|
||||
val ks = SymmetricKey.keyLength
|
||||
@ -142,14 +172,14 @@ sealed class KDF {
|
||||
salt, keySize
|
||||
)
|
||||
|
||||
Complexity.Sensitive -> Argon(
|
||||
Sensitive -> Argon(
|
||||
Alg.default,
|
||||
crypto_pwhash_OPSLIMIT_SENSITIVE,
|
||||
crypto_pwhash_MEMLIMIT_SENSITIVE,
|
||||
salt, keySize
|
||||
)
|
||||
|
||||
Complexity.FixedHigher -> Argon(
|
||||
FixedHigher -> Argon(
|
||||
V2id_13,
|
||||
4UL,
|
||||
1073741824,
|
||||
|
@ -38,4 +38,11 @@ class KDFTest {
|
||||
assertEquals(set2, set1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun complexityTest() = runTest{
|
||||
initCrypto()
|
||||
val kk = KDF.Complexity.Interactive.kdfForSize(3).deriveMultiple("lala", 3)
|
||||
assertEquals(3, kk.size)
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user