Skip to content

Commit 0a51432

Browse files
committed
Make it possible to set global default random used inside providers and simplify JDK provider setup
1 parent 2dc0536 commit 0a51432

File tree

19 files changed

+148
-57
lines changed

19 files changed

+148
-57
lines changed

cryptography-core/api/cryptography-core.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ public abstract interface class dev/whyoleg/cryptography/CryptographyProviderCon
7575
public final class dev/whyoleg/cryptography/CryptographySystem {
7676
public static final field INSTANCE Ldev/whyoleg/cryptography/CryptographySystem;
7777
public final fun getDefaultProvider ()Ldev/whyoleg/cryptography/CryptographyProvider;
78+
public final fun getDefaultRandom ()Ldev/whyoleg/cryptography/random/CryptographyRandom;
7879
public final fun getRegisteredProviders ()Ljava/util/List;
7980
public final fun registerProvider (Lkotlin/Lazy;I)V
8081
public final fun setDefaultProvider (Ldev/whyoleg/cryptography/CryptographyProvider;)V
82+
public final fun setDefaultRandom (Ldev/whyoleg/cryptography/random/CryptographyRandom;)V
8183
}
8284

8385
public abstract interface annotation class dev/whyoleg/cryptography/DelicateCryptographyApi : java/lang/annotation/Annotation {

cryptography-core/api/cryptography-core.klib.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,9 @@ final object dev.whyoleg.cryptography.algorithms/SHA512 : dev.whyoleg.cryptograp
835835

836836
final object dev.whyoleg.cryptography/CryptographySystem { // dev.whyoleg.cryptography/CryptographySystem|null[0]
837837
final fun getDefaultProvider(): dev.whyoleg.cryptography/CryptographyProvider // dev.whyoleg.cryptography/CryptographySystem.getDefaultProvider|getDefaultProvider(){}[0]
838+
final fun getDefaultRandom(): dev.whyoleg.cryptography.random/CryptographyRandom // dev.whyoleg.cryptography/CryptographySystem.getDefaultRandom|getDefaultRandom(){}[0]
838839
final fun getRegisteredProviders(): kotlin.collections/List<dev.whyoleg.cryptography/CryptographyProvider> // dev.whyoleg.cryptography/CryptographySystem.getRegisteredProviders|getRegisteredProviders(){}[0]
839840
final fun registerProvider(kotlin/Lazy<dev.whyoleg.cryptography/CryptographyProvider>, kotlin/Int) // dev.whyoleg.cryptography/CryptographySystem.registerProvider|registerProvider(kotlin.Lazy<dev.whyoleg.cryptography.CryptographyProvider>;kotlin.Int){}[0]
840841
final fun setDefaultProvider(dev.whyoleg.cryptography/CryptographyProvider) // dev.whyoleg.cryptography/CryptographySystem.setDefaultProvider|setDefaultProvider(dev.whyoleg.cryptography.CryptographyProvider){}[0]
842+
final fun setDefaultRandom(dev.whyoleg.cryptography.random/CryptographyRandom) // dev.whyoleg.cryptography/CryptographySystem.setDefaultRandom|setDefaultRandom(dev.whyoleg.cryptography.random.CryptographyRandom){}[0]
841843
}

cryptography-core/src/commonMain/kotlin/CryptographySystem.kt

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
package dev.whyoleg.cryptography
66

7+
import dev.whyoleg.cryptography.random.*
8+
79
// thread-unsafe, mutations should be used only during APP initialzation if needed
810
public object CryptographySystem {
911
private val impl = CryptographySystemImpl()
@@ -12,15 +14,16 @@ public object CryptographySystem {
1214
loadProviders()
1315
}
1416

15-
public fun getDefaultProvider(): CryptographyProvider = impl.getDefaultProvider()
16-
1717
// can be called at-most-once before calling `getDefaultProvider`
1818
public fun setDefaultProvider(provider: CryptographyProvider): Unit = impl.setDefaultProvider(provider)
19-
20-
public fun getRegisteredProviders(): List<CryptographyProvider> = impl.getRegisteredProviders()
19+
public fun getDefaultProvider(): CryptographyProvider = impl.getDefaultProvider()
2120

2221
// lower priority is better
2322
public fun registerProvider(provider: Lazy<CryptographyProvider>, priority: Int): Unit = impl.registerProvider(provider, priority)
23+
public fun getRegisteredProviders(): List<CryptographyProvider> = impl.getRegisteredProviders()
24+
25+
public fun setDefaultRandom(random: CryptographyRandom): Unit = impl.setDefaultRandom(random)
26+
public fun getDefaultRandom(): CryptographyRandom = impl.getDefaultRandom()
2427
}
2528

2629
// to be able to test this
@@ -42,6 +45,11 @@ internal class CryptographySystemImpl {
4245
}
4346
}
4447

48+
private var defaultRandom: CryptographyRandom? = null
49+
private val lazyDefaultRandom = lazy {
50+
defaultRandom ?: CryptographyRandom.Default
51+
}
52+
4553
fun getDefaultProvider(): CryptographyProvider = lazyDefaultProvider.value
4654

4755
// can be called at-most-once before calling `getDefaultProvider`
@@ -68,6 +76,15 @@ internal class CryptographySystemImpl {
6876
registeredProviders[priority] = provider
6977
}
7078

79+
fun setDefaultRandom(random: CryptographyRandom) {
80+
check(!lazyDefaultRandom.isInitialized()) { "Cannot set default random after `getDefaultRandom` was called" }
81+
check(defaultRandom == null) { "Default random already set" }
82+
83+
defaultRandom = random
84+
}
85+
86+
fun getDefaultRandom(): CryptographyRandom = lazyDefaultRandom.value
87+
7188
@OptIn(CryptographyProviderApi::class)
7289
private class CompositeProvider(
7390
private val providers: List<CryptographyProvider>,

cryptography-core/src/commonTest/kotlin/CryptographySystemTest.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,48 @@
44

55
package dev.whyoleg.cryptography
66

7+
import dev.whyoleg.cryptography.random.*
78
import kotlin.test.*
89

910
@OptIn(CryptographyProviderApi::class)
1011
class CryptographySystemTest {
1112
private fun testSystem(block: (system: CryptographySystemImpl) -> Unit) = block(CryptographySystemImpl())
1213

14+
@Test
15+
fun getDefaultRandomReturnsDefaultIfNotSet() = testSystem { system ->
16+
assertEquals(CryptographyRandom.Default, system.getDefaultRandom())
17+
}
18+
19+
@Test
20+
fun getDefaultRandomReturnsExplicitlySetProvider() = testSystem { system ->
21+
val random = TestRandom()
22+
system.setDefaultRandom(random)
23+
assertEquals(random, system.getDefaultRandom())
24+
}
25+
26+
@Test
27+
fun setDefaultRandomThrowsErrorIfAlreadySet() = testSystem { system ->
28+
val random = TestRandom()
29+
system.setDefaultRandom(random)
30+
31+
val exception = assertFailsWith<IllegalStateException> {
32+
system.setDefaultRandom(random)
33+
}
34+
assertEquals("Default random already set", exception.message)
35+
}
36+
37+
@Test
38+
fun setDefaultRandomThrowsErrorIfAlreadyAccessed() = testSystem { system ->
39+
val random = TestRandom()
40+
41+
assertEquals(CryptographyRandom.Default, system.getDefaultRandom())
42+
43+
val exception = assertFailsWith<IllegalStateException> {
44+
system.setDefaultRandom(random)
45+
}
46+
assertEquals("Cannot set default random after `getDefaultRandom` was called", exception.message)
47+
}
48+
1349
@Test
1450
fun registerProviderThrowsErrorWhenPriorityIsDuplicated() = testSystem { system ->
1551
val provider1 = TestCryptographyProvider("Provider1")
@@ -195,4 +231,10 @@ class CryptographySystemTest {
195231
class TestAlgorithm(override val id: CryptographyAlgorithmId<*>) : CryptographyAlgorithm
196232

197233
class TestAlgorithmId(name: String) : CryptographyAlgorithmId<TestAlgorithm>(name)
234+
235+
class TestRandom : CryptographyRandom() {
236+
override fun nextBits(bitCount: Int): Int {
237+
TODO("Not yet implemented")
238+
}
239+
}
198240
}

cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCAes.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
/*
2-
* Copyright (c) 2024 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright (c) 2024-2025 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package dev.whyoleg.cryptography.providers.apple.algorithms
66

77
import dev.whyoleg.cryptography.*
88
import dev.whyoleg.cryptography.algorithms.*
99
import dev.whyoleg.cryptography.materials.key.*
10-
import dev.whyoleg.cryptography.random.*
1110

1211
internal abstract class CCAes<K : AES.Key> : AES<K> {
1312
protected abstract fun wrapKey(key: ByteArray): K
@@ -31,7 +30,7 @@ internal abstract class CCAes<K : AES.Key> : AES<K> {
3130

3231
private inner class AesCtrKeyGenerator(private val keySizeBytes: Int) : KeyGenerator<K> {
3332
override fun generateKeyBlocking(): K {
34-
val key = CryptographyRandom.nextBytes(keySizeBytes)
33+
val key = CryptographySystem.getDefaultRandom().nextBytes(keySizeBytes)
3534
return wrapKey(key)
3635
}
3736
}

cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCAesIvCipher.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/*
2-
* Copyright (c) 2024 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright (c) 2024-2025 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package dev.whyoleg.cryptography.providers.apple.algorithms
66

7+
import dev.whyoleg.cryptography.*
78
import dev.whyoleg.cryptography.providers.apple.internal.*
89
import dev.whyoleg.cryptography.providers.base.algorithms.*
910
import dev.whyoleg.cryptography.providers.base.operations.*
10-
import dev.whyoleg.cryptography.random.*
1111
import platform.CoreCrypto.*
1212

1313
internal class CCAesIvCipher(
@@ -19,7 +19,7 @@ internal class CCAesIvCipher(
1919
private val validateCiphertextInputSize: (Int) -> Unit = {},
2020
) : BaseAesIvCipher {
2121
override fun createEncryptFunction(): CipherFunction {
22-
val iv = CryptographyRandom.nextBytes(ivSize)
22+
val iv = CryptographySystem.getDefaultRandom().nextBytes(ivSize)
2323
return BaseAesImplicitIvEncryptFunction(iv, createEncryptFunctionWithIv(iv))
2424
}
2525

cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCHmac.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023-2024 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright (c) 2023-2025 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package dev.whyoleg.cryptography.providers.apple.algorithms
@@ -10,7 +10,6 @@ import dev.whyoleg.cryptography.materials.key.*
1010
import dev.whyoleg.cryptography.operations.*
1111
import dev.whyoleg.cryptography.providers.apple.internal.*
1212
import dev.whyoleg.cryptography.providers.base.*
13-
import dev.whyoleg.cryptography.random.*
1413
import kotlinx.cinterop.*
1514
import platform.CoreCrypto.*
1615

@@ -54,7 +53,7 @@ private class HmacKeyGenerator(
5453
private val digestSize: Int,
5554
) : KeyGenerator<HMAC.Key> {
5655
override fun generateKeyBlocking(): HMAC.Key {
57-
val key = CryptographyRandom.nextBytes(blockSize)
56+
val key = CryptographySystem.getDefaultRandom().nextBytes(blockSize)
5857
return wrapKey(hmacAlgorithm, key, digestSize)
5958
}
6059
}

cryptography-providers/cryptokit/src/commonMain/kotlin/algorithms/CryptoKitAesGcm.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import dev.whyoleg.cryptography.providers.base.algorithms.*
1313
import dev.whyoleg.cryptography.providers.base.operations.*
1414
import dev.whyoleg.cryptography.providers.cryptokit.internal.*
1515
import dev.whyoleg.cryptography.providers.cryptokit.internal.swiftinterop.*
16-
import dev.whyoleg.cryptography.random.*
1716

1817
internal object CryptoKitAesGcm : AES.GCM {
1918
override fun keyDecoder(): KeyDecoder<AES.Key.Format, AES.GCM.Key> = AesKeyDecoder()
@@ -35,7 +34,7 @@ private class AesKeyDecoder : KeyDecoder<AES.Key.Format, AES.GCM.Key> {
3534

3635
private class AesGcmKeyGenerator(private val keySizeBytes: Int) : KeyGenerator<AES.GCM.Key> {
3736
override fun generateKeyBlocking(): AES.GCM.Key {
38-
val key = CryptographyRandom.nextBytes(keySizeBytes)
37+
val key = CryptographySystem.getDefaultRandom().nextBytes(keySizeBytes)
3938
return AesGcmKey(key)
4039
}
4140
}
@@ -59,7 +58,7 @@ private class AesGcmCipher(
5958
private val ivSize: Int get() = 12
6059

6160
override fun createEncryptFunction(associatedData: ByteArray?): CipherFunction {
62-
val iv = CryptographyRandom.nextBytes(ivSize)
61+
val iv = CryptographySystem.getDefaultRandom().nextBytes(ivSize)
6362
return BaseAesImplicitIvEncryptFunction(iv, createEncryptFunctionWithIv(iv, associatedData))
6463
}
6564

cryptography-providers/cryptokit/src/commonMain/kotlin/algorithms/CryptoKitHmac.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import dev.whyoleg.cryptography.materials.key.*
1010
import dev.whyoleg.cryptography.operations.*
1111
import dev.whyoleg.cryptography.providers.base.*
1212
import dev.whyoleg.cryptography.providers.cryptokit.internal.swiftinterop.*
13-
import dev.whyoleg.cryptography.random.*
1413
import kotlinx.cinterop.*
1514
import platform.CoreCrypto.*
1615
import platform.Foundation.*
@@ -58,7 +57,7 @@ private class HmacKeyGenerator(
5857
private val digestSize: Int,
5958
) : KeyGenerator<HMAC.Key> {
6059
override fun generateKeyBlocking(): HMAC.Key {
61-
val key = CryptographyRandom.nextBytes(blockSize)
60+
val key = CryptographySystem.getDefaultRandom().nextBytes(blockSize)
6261
return HmacKey(key, algorithm, digestSize)
6362
}
6463
}

cryptography-providers/jdk/api/cryptography-provider-jdk.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ public abstract interface class dev/whyoleg/cryptography/providers/jdk/DefaultJd
33
}
44

55
public final class dev/whyoleg/cryptography/providers/jdk/JdkCryptographyProviderKt {
6+
public static final fun JDK (Ldev/whyoleg/cryptography/CryptographyProvider$Companion;)Ldev/whyoleg/cryptography/CryptographyProvider;
67
public static final fun JDK (Ldev/whyoleg/cryptography/CryptographyProvider$Companion;Ldev/whyoleg/cryptography/random/CryptographyRandom;)Ldev/whyoleg/cryptography/CryptographyProvider;
78
public static final fun JDK (Ldev/whyoleg/cryptography/CryptographyProvider$Companion;Ljava/lang/String;Ldev/whyoleg/cryptography/random/CryptographyRandom;)Ldev/whyoleg/cryptography/CryptographyProvider;
89
public static final fun JDK (Ldev/whyoleg/cryptography/CryptographyProvider$Companion;Ljava/lang/String;Ljava/security/SecureRandom;)Ldev/whyoleg/cryptography/CryptographyProvider;
10+
public static final fun JDK (Ldev/whyoleg/cryptography/CryptographyProvider$Companion;Ljava/security/Provider;)Ldev/whyoleg/cryptography/CryptographyProvider;
911
public static final fun JDK (Ldev/whyoleg/cryptography/CryptographyProvider$Companion;Ljava/security/Provider;Ldev/whyoleg/cryptography/random/CryptographyRandom;)Ldev/whyoleg/cryptography/CryptographyProvider;
1012
public static final fun JDK (Ldev/whyoleg/cryptography/CryptographyProvider$Companion;Ljava/security/Provider;Ljava/security/SecureRandom;)Ldev/whyoleg/cryptography/CryptographyProvider;
1113
public static final fun JDK (Ldev/whyoleg/cryptography/CryptographyProvider$Companion;Ljava/security/SecureRandom;)Ldev/whyoleg/cryptography/CryptographyProvider;

cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,57 +14,91 @@ import java.util.concurrent.*
1414

1515
private val defaultProvider = lazy {
1616
val defaultSecurityProviders = loadViaServiceLoader().toList()
17-
when (defaultSecurityProviders.size) {
18-
0 -> CryptographyProvider.Companion.JDK()
19-
1 -> CryptographyProvider.Companion.JDK(defaultSecurityProviders.single().provider.value)
20-
else -> error("Multiple default JDK security providers found: $defaultSecurityProviders")
17+
if (defaultSecurityProviders.size > 1) {
18+
error("Multiple default JDK security providers found: $defaultSecurityProviders")
2119
}
20+
JdkCryptographyProvider(defaultSecurityProviders.singleOrNull()?.provider?.value)
2221
}
2322

23+
// uses default security provider registered
2424
public val CryptographyProvider.Companion.JDK: CryptographyProvider by defaultProvider
2525

26+
// uses all providers registered in the system
2627
@Suppress("FunctionName")
28+
public fun CryptographyProvider.Companion.JDK(): CryptographyProvider = JdkCryptographyProvider(null)
29+
30+
@Suppress("FunctionName")
31+
public fun CryptographyProvider.Companion.JDK(provider: Provider): CryptographyProvider = JdkCryptographyProvider(provider)
32+
33+
@Deprecated(
34+
message = "Secure random should be provided via CryptographySystem.setDefaultRandom",
35+
level = DeprecationLevel.ERROR,
36+
replaceWith = ReplaceWith("CryptographyProvider.JDK")
37+
)
38+
@Suppress("FunctionName", "DEPRECATION_ERROR")
2739
public fun CryptographyProvider.Companion.JDK(
2840
cryptographyRandom: CryptographyRandom = CryptographyRandom.Default,
2941
): CryptographyProvider = JDK(cryptographyRandom.asSecureRandom())
3042

31-
@Suppress("FunctionName")
43+
@Deprecated(
44+
message = "Secure random should be provided via CryptographySystem.setDefaultRandom",
45+
level = DeprecationLevel.ERROR,
46+
replaceWith = ReplaceWith("CryptographyProvider.JDK(provider)")
47+
)
48+
@Suppress("FunctionName", "DEPRECATION_ERROR")
3249
public fun CryptographyProvider.Companion.JDK(
3350
provider: Provider,
3451
cryptographyRandom: CryptographyRandom = CryptographyRandom.Default,
3552
): CryptographyProvider = JDK(provider, cryptographyRandom.asSecureRandom())
3653

37-
@Suppress("FunctionName")
54+
@Deprecated(
55+
message = "Overload with `provideName` is deprecated, use Security.getProvider(providerName) instead",
56+
level = DeprecationLevel.ERROR,
57+
replaceWith = ReplaceWith("CryptographyProvider.JDK(checkNotNull(Security.getProvider(providerName)))")
58+
)
59+
@Suppress("FunctionName", "DEPRECATION_ERROR")
3860
public fun CryptographyProvider.Companion.JDK(
3961
providerName: String,
4062
cryptographyRandom: CryptographyRandom = CryptographyRandom.Default,
4163
): CryptographyProvider = JDK(providerName, cryptographyRandom.asSecureRandom())
4264

65+
@Deprecated(
66+
message = "Secure random should be provided via CryptographySystem.setDefaultRandom",
67+
level = DeprecationLevel.ERROR,
68+
replaceWith = ReplaceWith("CryptographyProvider.JDK(provider)")
69+
)
4370
@Suppress("FunctionName")
4471
public fun CryptographyProvider.Companion.JDK(
4572
secureRandom: SecureRandom,
46-
): CryptographyProvider = JdkCryptographyProvider(null, secureRandom)
73+
): CryptographyProvider = JdkCryptographyProvider(null)
4774

75+
@Deprecated(
76+
message = "Secure random should be provided via CryptographySystem.setDefaultRandom",
77+
level = DeprecationLevel.ERROR,
78+
replaceWith = ReplaceWith("CryptographyProvider.JDK(provider)")
79+
)
4880
@Suppress("FunctionName")
4981
public fun CryptographyProvider.Companion.JDK(
5082
provider: Provider,
5183
secureRandom: SecureRandom,
52-
): CryptographyProvider = JdkCryptographyProvider(provider, secureRandom)
84+
): CryptographyProvider = JdkCryptographyProvider(provider)
5385

86+
@Deprecated(
87+
message = "Overload with `provideName` is deprecated, use Security.getProvider(providerName) instead",
88+
level = DeprecationLevel.ERROR,
89+
replaceWith = ReplaceWith("CryptographyProvider.JDK(checkNotNull(Security.getProvider(providerName)))")
90+
)
5491
@Suppress("FunctionName")
5592
public fun CryptographyProvider.Companion.JDK(
5693
providerName: String,
5794
secureRandom: SecureRandom,
5895
): CryptographyProvider {
5996
val provider = checkNotNull(Security.getProvider(providerName)) { "No provider with name: $providerName" }
60-
return JdkCryptographyProvider(provider, secureRandom)
97+
return JdkCryptographyProvider(provider)
6198
}
6299

63-
internal class JdkCryptographyProvider(
64-
provider: Provider?,
65-
secureRandom: SecureRandom,
66-
) : CryptographyProvider() {
67-
private val state = JdkCryptographyState(provider, secureRandom)
100+
internal class JdkCryptographyProvider(provider: Provider?) : CryptographyProvider() {
101+
private val state = JdkCryptographyState(provider)
68102
override val name: String = when (provider) {
69103
null -> "JDK"
70104
else -> "JDK (${provider.name})"

cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyState.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
/*
2-
* Copyright (c) 2023-2024 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright (c) 2023-2025 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package dev.whyoleg.cryptography.providers.jdk
66

77
import dev.whyoleg.cryptography.*
88
import dev.whyoleg.cryptography.algorithms.*
9+
import dev.whyoleg.cryptography.random.*
910
import java.util.concurrent.*
1011

11-
//candidate for context receivers
12-
internal class JdkCryptographyState(
13-
private val provider: JProvider?,
14-
val secureRandom: JSecureRandom,
15-
) {
12+
//candidate for context parameters
13+
internal class JdkCryptographyState(private val provider: JProvider?) {
14+
// TODO: move to something global?
15+
val secureRandom: JSecureRandom = CryptographySystem.getDefaultRandom().asSecureRandom()
1616

1717
private val ciphers: ConcurrentHashMap<String, Pooled<JCipher>> = ConcurrentHashMap()
1818
private val messageDigests: ConcurrentHashMap<String, Pooled<JMessageDigest>> = ConcurrentHashMap()

0 commit comments

Comments
 (0)