Factor getting secure random bytes into Crypto interface
This commit is contained in:
parent
a77d927624
commit
39cb0c6443
3 changed files with 23 additions and 3 deletions
|
@ -13,6 +13,7 @@ import java.io.IOException
|
|||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.security.GeneralSecurityException
|
||||
import java.security.SecureRandom
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
/**
|
||||
|
@ -33,6 +34,11 @@ import javax.crypto.spec.SecretKeySpec
|
|||
*/
|
||||
internal interface Crypto {
|
||||
|
||||
/**
|
||||
* Returns a ByteArray with bytes retrieved from [SecureRandom].
|
||||
*/
|
||||
fun getRandomBytes(size: Int): ByteArray
|
||||
|
||||
/**
|
||||
* Returns a [AesGcmHkdfStreaming] encrypting stream
|
||||
* that gets encrypted and authenticated the given associated data.
|
||||
|
@ -107,6 +113,11 @@ internal class CryptoImpl(
|
|||
private val key: ByteArray by lazy {
|
||||
deriveStreamKey(keyManager.getMainKey(), "app data key".toByteArray())
|
||||
}
|
||||
private val secureRandom: SecureRandom by lazy { SecureRandom() }
|
||||
|
||||
override fun getRandomBytes(size: Int) = ByteArray(size).apply {
|
||||
secureRandom.nextBytes(this)
|
||||
}
|
||||
|
||||
@Throws(IOException::class, GeneralSecurityException::class)
|
||||
override fun newEncryptingStream(
|
||||
|
|
|
@ -22,7 +22,6 @@ import kotlinx.coroutines.GlobalScope
|
|||
import kotlinx.coroutines.launch
|
||||
import org.calyxos.backup.storage.api.StorageBackup
|
||||
import java.io.IOException
|
||||
import java.security.SecureRandom
|
||||
|
||||
internal const val WORD_NUM = 12
|
||||
|
||||
|
@ -40,8 +39,7 @@ internal class RecoveryCodeViewModel(
|
|||
|
||||
internal val wordList: List<CharArray> by lazy {
|
||||
// we use our own entropy to not having to trust the library to use SecureRandom
|
||||
val entropy = ByteArray(Mnemonics.WordCount.COUNT_12.bitLength / 8)
|
||||
SecureRandom().nextBytes(entropy)
|
||||
val entropy = crypto.getRandomBytes(Mnemonics.WordCount.COUNT_12.bitLength / 8)
|
||||
// create the words from the entropy
|
||||
Mnemonics.MnemonicCode(entropy).words
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@ package com.stevesoltys.seedvault.crypto
|
|||
|
||||
import com.stevesoltys.seedvault.assertReadEquals
|
||||
import com.stevesoltys.seedvault.header.HeaderReaderImpl
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.Matchers.equalTo
|
||||
import org.hamcrest.Matchers.not
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
@ -21,6 +24,14 @@ class CryptoIntegrationTest {
|
|||
|
||||
private val cleartext = Random.nextBytes(Random.nextInt(1, 422300))
|
||||
|
||||
@Test
|
||||
fun `sanity check for getRandomBytes()`() {
|
||||
assertThat(crypto.getRandomBytes(42), not(equalTo(crypto.getRandomBytes(42))))
|
||||
assertThat(crypto.getRandomBytes(42), not(equalTo(crypto.getRandomBytes(42))))
|
||||
assertThat(crypto.getRandomBytes(42), not(equalTo(crypto.getRandomBytes(42))))
|
||||
assertThat(crypto.getRandomBytes(42), not(equalTo(crypto.getRandomBytes(42))))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `decrypting encrypted cleartext works`() {
|
||||
val ad = Random.nextBytes(42)
|
||||
|
|
Loading…
Reference in a new issue