All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pto.0.1.0.source-code.KeyStretcher.kt Maven / Gradle / Ivy

There is a newer version: 0.3.1
Show newest version
package se.wollan.crypto

import org.slf4j.Logger
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.PBEKeySpec
import kotlin.system.measureTimeMillis

// https://en.wikipedia.org/wiki/Key_stretching
internal interface KeyStretcher {
    fun stretch(weakKey: Pincode, salt: Salt, iterations: KeyStretchIterations): SecretKey
}

@JvmInline
value class KeyStretchIterations(val value: Int) {
    init {
        require(value >= minValue) { "too few iterations: $value" }
    }

    override fun toString() = value.toString()

    companion object {
        private const val minValue = 100_000
        val min = KeyStretchIterations(minValue)
        val default = KeyStretchIterations(1_000_000)
        val medium = KeyStretchIterations(500_000)
    }
}

// Same settings as https://mprimi.github.io/portable-secret/creator/
internal class PBKDF2KeyStretcher : KeyStretcher {

    override fun stretch(weakKey: Pincode, salt: Salt, iterations: KeyStretchIterations): SecretKey {
        val spec = PBEKeySpec(weakKey.value, salt.value, iterations.value, SecretKey.LEN_BYTES * 8)
        val factory = SecretKeyFactory.getInstance(ALG)
        val hash = factory.generateSecret(spec).encoded

        return SecretKey(hash)
    }

    companion object {
        private const val ALG = "PBKDF2WithHmacSHA1"
    }
}

internal class LoggingKeyStretcherDecorator(
    private val inner: KeyStretcher, private val logger: Logger
) : KeyStretcher {

    override fun stretch(weakKey: Pincode, salt: Salt, iterations: KeyStretchIterations): SecretKey {
        val result: SecretKey
        val ms = measureTimeMillis {
            result = inner.stretch(weakKey, salt, iterations)
        }
        logger.debug("key stretching with $iterations iterations took $ms ms")
        return result
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy