mirror of
https://github.com/tursom/TursomServer.git
synced 2025-01-14 22:30:48 +08:00
尝试添加不同分组加密工作模式
This commit is contained in:
parent
4643862bb7
commit
37b2cbfedd
@ -1,7 +1,10 @@
|
||||
package cn.tursom.core.datastruct
|
||||
|
||||
import cn.tursom.core.randomInt
|
||||
import cn.tursom.core.usingTime
|
||||
import java.io.Serializable
|
||||
import java.lang.reflect.Field
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.concurrent.atomic.AtomicLongArray
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -26,6 +29,7 @@ class AtomicBitSet(beginSize: Long = 256, val defaultState: Boolean = false) : S
|
||||
bitSet.array.forEach { count += it.bitCount }
|
||||
return count
|
||||
}
|
||||
val upCount get() = trueCount
|
||||
|
||||
init {
|
||||
val default = if (defaultState) -1L else 0L
|
||||
@ -83,7 +87,33 @@ class AtomicBitSet(beginSize: Long = 256, val defaultState: Boolean = false) : S
|
||||
}
|
||||
|
||||
fun firstUp(): Long {
|
||||
bitSet.forEachIndexed { index, l ->
|
||||
return scanUp(0, bitSet.length())
|
||||
}
|
||||
|
||||
fun randomUpIndex(): Long {
|
||||
val startIndex = Random.nextInt(bitSet.length())
|
||||
var scan = scanUp(startIndex, bitSet.length() - startIndex)
|
||||
if (scan >= 0) return scan
|
||||
scan = scanUp(startIndex - 1, startIndex, false)
|
||||
if (scan >= 0) return scan
|
||||
return -1
|
||||
}
|
||||
|
||||
fun firstDown(): Long {
|
||||
return scanDown(0, bitSet.length())
|
||||
}
|
||||
|
||||
fun getDownIndex(): Long {
|
||||
val startIndex = Random.nextInt(bitSet.length())
|
||||
var scan = scanDown(startIndex, bitSet.length() - startIndex)
|
||||
if (scan >= 0) return scan
|
||||
scan = scanDown(startIndex - 1, startIndex, false)
|
||||
if (scan >= 0) return scan
|
||||
return -1
|
||||
}
|
||||
|
||||
private fun scanUp(fromIndex: Int, length: Int, asc: Boolean = true): Long {
|
||||
bitSet.forEachIndexed(fromIndex, length, asc) { index, l ->
|
||||
if (l != 0L) {
|
||||
for (i in 0 until 8) {
|
||||
if (l and scanArray[i] != 0L) {
|
||||
@ -98,19 +128,6 @@ class AtomicBitSet(beginSize: Long = 256, val defaultState: Boolean = false) : S
|
||||
return -1
|
||||
}
|
||||
|
||||
fun firstDown(): Long {
|
||||
return scanDown(0, bitSet.length())
|
||||
}
|
||||
|
||||
fun getDownIndex(): Long {
|
||||
val startIndex = Random.nextInt(0, bitSet.length())
|
||||
var scan = scanDown(startIndex, bitSet.length() - startIndex)
|
||||
if (scan >= 0) return scan
|
||||
scan = scanDown(startIndex - 1, startIndex, false)
|
||||
if (scan >= 0) return scan
|
||||
return -1
|
||||
}
|
||||
|
||||
private fun scanDown(fromIndex: Int, length: Int, asc: Boolean = true): Long {
|
||||
bitSet.forEachIndexed(fromIndex, length, asc) { index, l ->
|
||||
if (l != -1L) {
|
||||
@ -193,21 +210,45 @@ class AtomicBitSet(beginSize: Long = 256, val defaultState: Boolean = false) : S
|
||||
array.isAccessible = true
|
||||
}
|
||||
|
||||
inline fun AtomicLongArray.forEachIndexed(action: (index: Int, Long) -> Unit) {
|
||||
private inline fun AtomicLongArray.forEachIndexed(action: (index: Int, Long) -> Unit) {
|
||||
repeat(length()) {
|
||||
action(it, get(it))
|
||||
}
|
||||
}
|
||||
|
||||
inline fun AtomicLongArray.forEachIndexed(startIndex: Int, length: Int = length(), asc: Boolean = true, action: (index: Int, Long) -> Unit) {
|
||||
private inline fun AtomicLongArray.forEachIndexed(startIndex: Int, length: Int = length(), asc: Boolean = true, action: (index: Int, Long) -> Unit) {
|
||||
repeat(length) {
|
||||
val index = if (asc) {
|
||||
startIndex + it
|
||||
} else {
|
||||
startIndex - it
|
||||
}
|
||||
//scand.incrementAndGet()
|
||||
action(index, get(index))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//val scand = AtomicInteger(0)
|
||||
|
||||
fun main() {
|
||||
val size = 1000000
|
||||
val bitSet = AtomicBitSet(size.toLong())
|
||||
println(usingTime {
|
||||
repeat(1000) {
|
||||
bitSet.downAll()
|
||||
repeat(size) {
|
||||
val index = bitSet.getDownIndex()
|
||||
bitSet.up(index)
|
||||
repeat(randomInt(0, 3) / 2) {
|
||||
val randomUpIndex = bitSet.randomUpIndex()
|
||||
if (randomUpIndex >= 0) {
|
||||
bitSet.down(randomUpIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
//println(scand.get() / 100)
|
||||
}
|
@ -1,14 +1,21 @@
|
||||
package cn.tursom.core.encrypt
|
||||
|
||||
import cn.tursom.core.toHexString
|
||||
import cn.tursom.core.toUTF8String
|
||||
import java.security.*
|
||||
import java.security.interfaces.RSAPublicKey
|
||||
import java.security.spec.X509EncodedKeySpec
|
||||
import javax.crypto.Cipher
|
||||
import kotlin.experimental.xor
|
||||
import kotlin.math.min
|
||||
import kotlin.random.Random
|
||||
|
||||
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
abstract class AbstractPublicKeyEncrypt(
|
||||
val algorithm: String,
|
||||
final override val publicKey: PublicKey,
|
||||
final override val privateKey: PrivateKey? = null
|
||||
final override val privateKey: PrivateKey? = null,
|
||||
val modeOfOperation: BlockCipherModeOfOperation = BlockCipherModeOfOperation.ECB,
|
||||
) : PublicKeyEncrypt {
|
||||
val publicKeyEncoded get() = publicKey.encoded!!
|
||||
val privateKeyEncoded get() = privateKey?.encoded
|
||||
@ -39,67 +46,56 @@ abstract class AbstractPublicKeyEncrypt(
|
||||
override fun signature(digest: String): String = this@AbstractPublicKeyEncrypt.signature(digest)
|
||||
}
|
||||
|
||||
constructor(algorithm: String, keyPair: KeyPair) : this(algorithm, keyPair.public as PublicKey, keyPair.private as PrivateKey)
|
||||
|
||||
constructor(algorithm: String, keySize: Int = 1024) : this(algorithm, KeyPairGenerator.getInstance(algorithm).let {
|
||||
it.initialize(keySize)
|
||||
it.generateKeyPair()
|
||||
})
|
||||
|
||||
constructor(algorithm: String, publicKey: ByteArray) : this(algorithm, KeyFactory.getInstance(algorithm).generatePublic(X509EncodedKeySpec(publicKey)) as PublicKey)
|
||||
|
||||
override fun encrypt(data: ByteArray, offset: Int, size: Int): ByteArray {
|
||||
return if (size < encryptMaxLen) {
|
||||
encryptCipher.doFinal(data, offset, size)
|
||||
} else {
|
||||
val buffer = ByteArray(((size - 1) / encryptMaxLen + 1) * decryptMaxLen)
|
||||
buffer.copyOf(doFinal(data, offset, size, buffer, encryptCipher, encryptMaxLen))
|
||||
}
|
||||
private val blockCipher: Encrypt = when (modeOfOperation) {
|
||||
BlockCipherModeOfOperation.ECB -> ECBBlockCipher()
|
||||
BlockCipherModeOfOperation.CBC -> CBCBlockCipher()
|
||||
else -> TODO()
|
||||
}
|
||||
|
||||
override fun decrypt(data: ByteArray, offset: Int, size: Int): ByteArray {
|
||||
return if (data.size < decryptMaxLen) {
|
||||
decryptCipher.doFinal(data, offset, size)
|
||||
} else {
|
||||
val buffer = ByteArray(size / decryptMaxLen * encryptMaxLen + 11)
|
||||
buffer.copyOf(doFinal(data, offset, size, buffer, decryptCipher, decryptMaxLen))
|
||||
override var encryptInitVector: ByteArray?
|
||||
get() = blockCipher.encryptInitVector
|
||||
set(value) {
|
||||
blockCipher.encryptInitVector = value
|
||||
}
|
||||
override var decryptInitVector: ByteArray?
|
||||
get() = blockCipher.decryptInitVector
|
||||
set(value) {
|
||||
blockCipher.decryptInitVector = value
|
||||
}
|
||||
}
|
||||
|
||||
override fun encrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int {
|
||||
return if (data.size < decryptMaxLen) {
|
||||
encryptCipher.doFinal(data, offset, size, buffer, bufferOffset)
|
||||
} else {
|
||||
doFinal(data, offset, size, buffer, encryptCipher, decryptMaxLen, bufferOffset)
|
||||
}
|
||||
}
|
||||
constructor(
|
||||
algorithm: String,
|
||||
keyPair: KeyPair,
|
||||
modeOfOperation: BlockCipherModeOfOperation = BlockCipherModeOfOperation.ECB,
|
||||
) : this(algorithm, keyPair.public as PublicKey, keyPair.private as PrivateKey, modeOfOperation = modeOfOperation)
|
||||
|
||||
override fun decrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int {
|
||||
return if (data.size < decryptMaxLen) {
|
||||
decryptCipher.doFinal(data, offset, size, buffer, bufferOffset)
|
||||
} else {
|
||||
doFinal(data, offset, size, buffer, decryptCipher, decryptMaxLen, bufferOffset)
|
||||
}
|
||||
}
|
||||
constructor(
|
||||
algorithm: String,
|
||||
keySize: Int = 1024,
|
||||
modeOfOperation: BlockCipherModeOfOperation = BlockCipherModeOfOperation.ECB,
|
||||
) : this(
|
||||
algorithm,
|
||||
KeyPairGenerator.getInstance(algorithm).let {
|
||||
it.initialize(keySize)
|
||||
it.generateKeyPair()
|
||||
},
|
||||
modeOfOperation = modeOfOperation
|
||||
)
|
||||
|
||||
private fun doFinal(
|
||||
data: ByteArray,
|
||||
offset: Int,
|
||||
size: Int,
|
||||
buffer: ByteArray,
|
||||
cipher: Cipher,
|
||||
blockSize: Int,
|
||||
bufferOffset: Int = 0
|
||||
): Int {
|
||||
var readPosition = offset
|
||||
var writeIndex = bufferOffset
|
||||
while (readPosition + blockSize < size) {
|
||||
writeIndex += cipher.doFinal(data, readPosition, blockSize, buffer, writeIndex)
|
||||
readPosition += blockSize
|
||||
}
|
||||
writeIndex += cipher.doFinal(data, readPosition, size - readPosition, buffer, writeIndex)
|
||||
return writeIndex - bufferOffset
|
||||
}
|
||||
constructor(
|
||||
algorithm: String,
|
||||
publicKey: ByteArray,
|
||||
modeOfOperation: BlockCipherModeOfOperation = BlockCipherModeOfOperation.ECB,
|
||||
) : this(
|
||||
algorithm,
|
||||
KeyFactory.getInstance(algorithm).generatePublic(X509EncodedKeySpec(publicKey)) as PublicKey,
|
||||
modeOfOperation = modeOfOperation
|
||||
)
|
||||
|
||||
override fun encrypt(data: ByteArray, offset: Int, size: Int): ByteArray = blockCipher.encrypt(data, offset, size)
|
||||
override fun decrypt(data: ByteArray, offset: Int, size: Int): ByteArray = blockCipher.decrypt(data, offset, size)
|
||||
override fun encrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int = blockCipher.encrypt(data, buffer, bufferOffset, offset, size)
|
||||
override fun decrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int = blockCipher.decrypt(data, buffer, bufferOffset, offset, size)
|
||||
|
||||
protected open fun signature(digest: String) = "${digest}with$algorithm"
|
||||
|
||||
@ -134,4 +130,162 @@ abstract class AbstractPublicKeyEncrypt(
|
||||
result = 31 * result + (privateKey?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
protected inner class ECBBlockCipher : Encrypt {
|
||||
override fun encrypt(data: ByteArray, offset: Int, size: Int): ByteArray {
|
||||
return if (size < encryptMaxLen) {
|
||||
encryptCipher.doFinal(data, offset, size)
|
||||
} else {
|
||||
val buffer = ByteArray(((size - 1) / encryptMaxLen + 1) * decryptMaxLen)
|
||||
buffer.copyOf(doFinal(data, offset, size, buffer, encryptCipher, encryptMaxLen))
|
||||
}
|
||||
}
|
||||
|
||||
override fun decrypt(data: ByteArray, offset: Int, size: Int): ByteArray {
|
||||
return if (data.size < decryptMaxLen) {
|
||||
decryptCipher.doFinal(data, offset, size)
|
||||
} else {
|
||||
val buffer = ByteArray(size / decryptMaxLen * encryptMaxLen + 11)
|
||||
buffer.copyOf(doFinal(data, offset, size, buffer, decryptCipher, decryptMaxLen))
|
||||
}
|
||||
}
|
||||
|
||||
override fun encrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int {
|
||||
return if (data.size < decryptMaxLen) {
|
||||
encryptCipher.doFinal(data, offset, size, buffer, bufferOffset)
|
||||
} else {
|
||||
doFinal(data, offset, size, buffer, encryptCipher, decryptMaxLen, bufferOffset)
|
||||
}
|
||||
}
|
||||
|
||||
override fun decrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int {
|
||||
return if (data.size < decryptMaxLen) {
|
||||
decryptCipher.doFinal(data, offset, size, buffer, bufferOffset)
|
||||
} else {
|
||||
doFinal(data, offset, size, buffer, decryptCipher, decryptMaxLen, bufferOffset)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doFinal(
|
||||
data: ByteArray,
|
||||
offset: Int,
|
||||
size: Int,
|
||||
buffer: ByteArray,
|
||||
cipher: Cipher,
|
||||
blockSize: Int,
|
||||
bufferOffset: Int = 0,
|
||||
): Int {
|
||||
var readPosition = offset
|
||||
var writeIndex = bufferOffset
|
||||
while (readPosition + blockSize < size) {
|
||||
writeIndex += cipher.doFinal(data, readPosition, blockSize, buffer, writeIndex)
|
||||
readPosition += blockSize
|
||||
}
|
||||
writeIndex += cipher.doFinal(data, readPosition, size - readPosition, buffer, writeIndex)
|
||||
return writeIndex - bufferOffset
|
||||
}
|
||||
}
|
||||
|
||||
protected inner class CBCBlockCipher : Encrypt {
|
||||
override var encryptInitVector: ByteArray? = Random.nextBytes(encryptMaxLen)
|
||||
set(value) {
|
||||
value ?: return
|
||||
field = value
|
||||
encBuf = value
|
||||
}
|
||||
override var decryptInitVector: ByteArray? = null
|
||||
set(value) {
|
||||
field = value
|
||||
decBuf = value
|
||||
}
|
||||
|
||||
private var encBuf = encryptInitVector!!
|
||||
private var decBuf: ByteArray? = decryptInitVector
|
||||
|
||||
override fun encrypt(data: ByteArray, offset: Int, size: Int): ByteArray {
|
||||
val buffer = ByteArray(((size - 1) / encryptMaxLen + 1) * decryptMaxLen)
|
||||
//return buffer.copyOf(encrypt(data, buffer, 0, offset, size))
|
||||
encrypt(data, buffer, 0, offset, size)
|
||||
return buffer
|
||||
}
|
||||
|
||||
override fun encrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int {
|
||||
var end = offset
|
||||
var start: Int
|
||||
var writeIndex = bufferOffset
|
||||
do {
|
||||
start = end
|
||||
end += encryptMaxLen
|
||||
end = min(data.size, end)
|
||||
(0 until end - start).forEach { index ->
|
||||
encBuf[index] = encBuf[index] xor data[start + index]
|
||||
}
|
||||
writeIndex += encryptCipher.doFinal(encBuf, 0, encBuf.size, buffer, writeIndex)
|
||||
//println("${data.size} $start->$end $writeIndex")
|
||||
} while (end < offset + size)
|
||||
return writeIndex - bufferOffset
|
||||
}
|
||||
|
||||
override fun decrypt(data: ByteArray, offset: Int, size: Int): ByteArray {
|
||||
val decryptInitVector = decBuf!!
|
||||
var start: Int
|
||||
var end = offset
|
||||
val buffer = ByteArray(((size - 1) / decryptMaxLen + 1) * encryptMaxLen + 11)
|
||||
var writeIndex = 0
|
||||
do {
|
||||
start = end
|
||||
end += decryptMaxLen
|
||||
end = min(data.size, end)
|
||||
println("${data.size}, $start->$end, ${buffer.size}, $writeIndex")
|
||||
val writeIndexBefore = writeIndex
|
||||
writeIndex += decryptCipher.doFinal(data, start, end - start, buffer, writeIndex)
|
||||
if (start == 0) {
|
||||
repeat(encryptMaxLen) {
|
||||
buffer[it] = buffer[it] xor decryptInitVector[it]
|
||||
}
|
||||
} else {
|
||||
repeat(writeIndex - writeIndexBefore) {
|
||||
buffer[writeIndexBefore + it] = buffer[writeIndexBefore + it] xor data[start + it]
|
||||
}
|
||||
}
|
||||
} while (end < offset + size)
|
||||
decBuf = buffer.copyOfRange(buffer.size - encryptMaxLen, buffer.size)
|
||||
return buffer.copyOf(writeIndex)
|
||||
}
|
||||
|
||||
override fun decrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
//private fun doFinal(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int, cipher: Cipher): Int {
|
||||
// var start = offset
|
||||
// var end = offset
|
||||
// var writeIndex = bufferOffset
|
||||
// do {
|
||||
// end += decryptMaxLen
|
||||
// end = min(data.size, end)
|
||||
// encBuf.indices.forEach { index ->
|
||||
// encBuf[index] = encBuf[index] xor data[start + index]
|
||||
// }
|
||||
// writeIndex += cipher.doFinal(encBuf, 0, encBuf.size, buffer, writeIndex)
|
||||
// start += decryptMaxLen
|
||||
// } while (end < offset + size)
|
||||
// return writeIndex - bufferOffset
|
||||
//}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val random = Random(System.currentTimeMillis())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun main() {
|
||||
val source = "HelloWorld".repeat(100).toByteArray()
|
||||
val rsa = RSA()
|
||||
val decodeRsa = rsa.public
|
||||
decodeRsa.decryptInitVector = rsa.encryptInitVector
|
||||
val encrypt = rsa.encrypt(source)
|
||||
//println(encrypt.toHexString())
|
||||
println(decodeRsa.decrypt(encrypt).toUTF8String())
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package cn.tursom.core.encrypt
|
||||
|
||||
enum class BlockCipherModeOfOperation {
|
||||
ECB, CBC, CFB, OFB, CTR,
|
||||
}
|
@ -3,6 +3,13 @@ package cn.tursom.core.encrypt
|
||||
import cn.tursom.core.buffer.ByteBuffer
|
||||
|
||||
interface Encrypt {
|
||||
var encryptInitVector: ByteArray?
|
||||
get() = null
|
||||
set(_) {}
|
||||
var decryptInitVector: ByteArray?
|
||||
get() = null
|
||||
set(_) {}
|
||||
|
||||
fun encrypt(data: ByteArray, offset: Int = 0, size: Int = data.size - offset): ByteArray
|
||||
fun decrypt(data: ByteArray, offset: Int = 0, size: Int = data.size - offset): ByteArray
|
||||
fun encrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int = 0, offset: Int = 0, size: Int = data.size - offset): Int
|
||||
|
@ -10,28 +10,49 @@ import java.security.spec.X509EncodedKeySpec
|
||||
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
class RSA(
|
||||
publicKey: RSAPublicKey,
|
||||
privateKey: RSAPrivateKey? = null
|
||||
) : AbstractPublicKeyEncrypt("RSA", publicKey, privateKey) {
|
||||
privateKey: RSAPrivateKey? = null,
|
||||
modeOfOperation: BlockCipherModeOfOperation = BlockCipherModeOfOperation.ECB,
|
||||
) : AbstractPublicKeyEncrypt("RSA", publicKey, privateKey, modeOfOperation = modeOfOperation) {
|
||||
|
||||
val keySize = publicKey.modulus.bitLength()
|
||||
override val decryptMaxLen = keySize / 8
|
||||
override val encryptMaxLen = decryptMaxLen - 11
|
||||
val keySize get() = (publicKey as RSAPublicKey).modulus.bitLength()
|
||||
override val decryptMaxLen get() = keySize / 8
|
||||
override val encryptMaxLen get() = decryptMaxLen - 11
|
||||
|
||||
override val public by lazy {
|
||||
override val public by lazy {
|
||||
if (privateKey == null) {
|
||||
this
|
||||
} else {
|
||||
RSA(publicKey)
|
||||
RSA(publicKey, modeOfOperation = modeOfOperation)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(keyPair: KeyPair) : this(keyPair.public as RSAPublicKey, keyPair.private as RSAPrivateKey)
|
||||
constructor(
|
||||
keyPair: KeyPair,
|
||||
modeOfOperation: BlockCipherModeOfOperation = BlockCipherModeOfOperation.ECB,
|
||||
) : this(
|
||||
keyPair.public as RSAPublicKey,
|
||||
keyPair.private as RSAPrivateKey,
|
||||
modeOfOperation
|
||||
)
|
||||
|
||||
constructor(keySize: Int = 1024) : this(KeyPairGenerator.getInstance("RSA").let {
|
||||
it.initialize(keySize)
|
||||
it.generateKeyPair()
|
||||
})
|
||||
constructor(
|
||||
keySize: Int = 1024,
|
||||
modeOfOperation: BlockCipherModeOfOperation = BlockCipherModeOfOperation.ECB,
|
||||
) : this(
|
||||
KeyPairGenerator.getInstance("RSA").let {
|
||||
it.initialize(keySize)
|
||||
it.generateKeyPair()
|
||||
},
|
||||
modeOfOperation
|
||||
)
|
||||
|
||||
constructor(publicKey: ByteArray) : this(KeyFactory.getInstance("RSA").generatePublic(X509EncodedKeySpec(publicKey)) as RSAPublicKey)
|
||||
constructor(
|
||||
publicKey: ByteArray,
|
||||
modeOfOperation: BlockCipherModeOfOperation = BlockCipherModeOfOperation.ECB,
|
||||
) : this(
|
||||
KeyFactory.getInstance("RSA").generatePublic(X509EncodedKeySpec(publicKey)) as RSAPublicKey,
|
||||
null,
|
||||
modeOfOperation
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user