RSA wrapper written in Kotlin The 2019 Stack Overflow Developer Survey Results Are In Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)Encrypting a binary stream with RSA + AES in counter modeEncryption wrapperAdds digital signature to outgoing TCP packetImplementing RSA-AES encryption protocolMy images have secrets A.K.A. the making of aesthetic passwords V.2RSA algorithm implementation in Python 3Home-grown encryption/decryption functionVerify OpenSSL RSA signature (PHP) with .NET (VB)Python RSA/DSA File Cryptography, Key Generation, Key ProtectionEncrypts using AES with random initialization vector meant for data with limited visibility and then long rest
Python - Fishing Simulator
How do I add random spotting to the same face in cycles?
Why can't wing-mounted spoilers be used to steepen approaches?
Semisimplicity of the category of coherent sheaves?
Did God make two great lights or did He make the great light two?
Is it ethical to upload a automatically generated paper to a non peer-reviewed site as part of a larger research?
Difference between "generating set" and free product?
Why did all the guest students take carriages to the Yule Ball?
Slither Like a Snake
I could not break this equation. Please help me
Mortgage adviser recommends a longer term than necessary combined with overpayments
How many people can fit inside Mordenkainen's Magnificent Mansion?
Wolves and sheep
What is special about square numbers here?
How can I define good in a religion that claims no moral authority?
Wall plug outlet change
Cooking pasta in a water boiler
Reference for the teaching of not-self
Windows 10: How to Lock (not sleep) laptop on lid close?
When did F become S in typeography, and why?
What force causes entropy to increase?
Typeface like Times New Roman but with "tied" percent sign
Can smartphones with the same camera sensor have different image quality?
"... to apply for a visa" or "... and applied for a visa"?
RSA wrapper written in Kotlin
The 2019 Stack Overflow Developer Survey Results Are In
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)Encrypting a binary stream with RSA + AES in counter modeEncryption wrapperAdds digital signature to outgoing TCP packetImplementing RSA-AES encryption protocolMy images have secrets A.K.A. the making of aesthetic passwords V.2RSA algorithm implementation in Python 3Home-grown encryption/decryption functionVerify OpenSSL RSA signature (PHP) with .NET (VB)Python RSA/DSA File Cryptography, Key Generation, Key ProtectionEncrypts using AES with random initialization vector meant for data with limited visibility and then long rest
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
I've written up a small wrapper for RSA and AES encryption in Kotlin, and I want to make sure I'm not making any glaring mistakes before use it. This is going on a small project with basically no needed security, but I wanted to try and write it correctly.
Here's my Person
class:
class Person private constructor(val name :String,
private val keyPair: KeyPair) {
val publicKey : PublicKey
get() = keyPair.public
private val privateKey : PrivateKey
get() = keyPair.private ?: error("Current Person implementation doesn't support functions that use the private key")
fun isValid() = fromPrivateKey(name,privateKey).publicKey == publicKey
override fun toString(): String
return "Person(name=$name, finger=$fingerprint().substring(0,10))"
fun sign(data :ByteArray): Signature
sig.initSign(privateKey)
sig.update(data)
return Signature(sig.sign())
fun fingerprint():String = DigestUtils.sha1Hex(publicKey.encoded)
/** This needs to be below 245 bytes */
fun encrypt(data :ByteArray, publicKey: PublicKey): ByteArray
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
return cipher.doFinal(data)
/** This needs to be below 245 bytes */
fun encrypt(data :ByteArray, person :Person):ByteArray = encrypt(data,person.publicKey)
/** This needs to be below 245 bytes */
fun decrypt(encrypted: ByteArray): ByteArray
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
return cipher.doFinal(encrypted)
/** This will encrypt over 245 bytes */
fun encryptAES(data :ByteArray,person :Person):EncryptedData = encryptAES(data,person.publicKey)
/** This will encrypt over 245 bytes */
fun encryptAES(data :ByteArray, publicKey : PublicKey): EncryptedData
val iv = ByteArray(16) -1
SecureRandom.getInstanceStrong().nextBytes(iv)
val keyGen = KeyGenerator.getInstance("AES")
keyGen.init(128)
val secretKey = keyGen.generateKey()
val ivParameterSpec = IvParameterSpec(iv)
val aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
val final = aesCipher.doFinal(data)
return EncryptedData(iv, encrypt(secretKey.encoded,publicKey), final)
//need to return encrypted secret key and the encrypted message
fun decryptAES(data : EncryptedData) :ByteArray
val iv = data.iv
val ivParameterSpec = IvParameterSpec(iv)
val decryptedSecretKey = decrypt(data.encryptedSecretKey)
val secretKey = SecretKeySpec(decryptedSecretKey, 0, decryptedSecretKey.size, "AES")
val aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
aesCipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
return aesCipher.doFinal(data.encryptedData)
And then I use the Companion object to make new instances of this class:
companion object
private val sig = java.security.Signature.getInstance("SHA1WithRSA")
fun verify(publicKey: PublicKey, signature: Signature, data: ByteArray): Boolean
sig.initVerify(publicKey)
sig.update(data)
return sig.verify(signature.byteArray)
//buildKeyPair(DigestUtils.sha1(name)!!.contentHashCode().toLong())
private fun buildKeyPair(seed :Long): KeyPair
val random = SecureRandom.getInstance("SHA1PRNG")
random.setSeed(seed)
val keySize = 2048
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(keySize,random)
return keyPairGenerator.genKeyPair()
private fun buildKeyPair():KeyPair
val keySize = 2048
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(keySize)
return keyPairGenerator.genKeyPair()
//generators
fun fromKeyPair(name :String, keyPair: KeyPair):Person = Person(name, keyPair)
fun fromPublicKey(name :String, publicKey: PublicKey):Person = Person(name,KeyPair(publicKey,null))
fun fromPrivateKey(name :String, privateKey: PrivateKey):Person
//attempt to find the correct public key
if(privateKey !is RSAPrivateCrtKey)
error("Private key is not a RSAPrivateCrtKey and does not contain enough data to compute the public key")
val spec = RSAPublicKeySpec(privateKey.modulus,privateKey.publicExponent)
val factory = KeyFactory.getInstance("RSA")
val publicKey = factory.generatePublic(spec)
return Person(name, KeyPair(publicKey,privateKey))
fun deterministicFromName(name :String) :Person = Person(name,buildKeyPair(DigestUtils.sha1(name)!!.contentHashCode().toLong()))
fun generateNew(name :String) :Person = Person(name, buildKeyPair())
This also uses these classes:
class Signature(val byteArray: ByteArray)
override fun equals(other: Any?): Boolean
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Signature
if (!byteArray.contentEquals(other.byteArray)) return false
return true
override fun hashCode(): Int
return byteArray.contentHashCode()
and
class EncryptedData(val iv :ByteArray, val encryptedSecretKey :ByteArray,val encryptedData :ByteArray)
I'm using RSA keys to encrypt a randomly generated AES key, which can be used to encrypt data that is larger than 245 bytes.
The idea is that I can pass public keys around but treat everything as a Person
, and then throw an error if the private key is invalid. Is this a good design?
security cryptography kotlin
New contributor
$endgroup$
add a comment |
$begingroup$
I've written up a small wrapper for RSA and AES encryption in Kotlin, and I want to make sure I'm not making any glaring mistakes before use it. This is going on a small project with basically no needed security, but I wanted to try and write it correctly.
Here's my Person
class:
class Person private constructor(val name :String,
private val keyPair: KeyPair) {
val publicKey : PublicKey
get() = keyPair.public
private val privateKey : PrivateKey
get() = keyPair.private ?: error("Current Person implementation doesn't support functions that use the private key")
fun isValid() = fromPrivateKey(name,privateKey).publicKey == publicKey
override fun toString(): String
return "Person(name=$name, finger=$fingerprint().substring(0,10))"
fun sign(data :ByteArray): Signature
sig.initSign(privateKey)
sig.update(data)
return Signature(sig.sign())
fun fingerprint():String = DigestUtils.sha1Hex(publicKey.encoded)
/** This needs to be below 245 bytes */
fun encrypt(data :ByteArray, publicKey: PublicKey): ByteArray
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
return cipher.doFinal(data)
/** This needs to be below 245 bytes */
fun encrypt(data :ByteArray, person :Person):ByteArray = encrypt(data,person.publicKey)
/** This needs to be below 245 bytes */
fun decrypt(encrypted: ByteArray): ByteArray
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
return cipher.doFinal(encrypted)
/** This will encrypt over 245 bytes */
fun encryptAES(data :ByteArray,person :Person):EncryptedData = encryptAES(data,person.publicKey)
/** This will encrypt over 245 bytes */
fun encryptAES(data :ByteArray, publicKey : PublicKey): EncryptedData
val iv = ByteArray(16) -1
SecureRandom.getInstanceStrong().nextBytes(iv)
val keyGen = KeyGenerator.getInstance("AES")
keyGen.init(128)
val secretKey = keyGen.generateKey()
val ivParameterSpec = IvParameterSpec(iv)
val aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
val final = aesCipher.doFinal(data)
return EncryptedData(iv, encrypt(secretKey.encoded,publicKey), final)
//need to return encrypted secret key and the encrypted message
fun decryptAES(data : EncryptedData) :ByteArray
val iv = data.iv
val ivParameterSpec = IvParameterSpec(iv)
val decryptedSecretKey = decrypt(data.encryptedSecretKey)
val secretKey = SecretKeySpec(decryptedSecretKey, 0, decryptedSecretKey.size, "AES")
val aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
aesCipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
return aesCipher.doFinal(data.encryptedData)
And then I use the Companion object to make new instances of this class:
companion object
private val sig = java.security.Signature.getInstance("SHA1WithRSA")
fun verify(publicKey: PublicKey, signature: Signature, data: ByteArray): Boolean
sig.initVerify(publicKey)
sig.update(data)
return sig.verify(signature.byteArray)
//buildKeyPair(DigestUtils.sha1(name)!!.contentHashCode().toLong())
private fun buildKeyPair(seed :Long): KeyPair
val random = SecureRandom.getInstance("SHA1PRNG")
random.setSeed(seed)
val keySize = 2048
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(keySize,random)
return keyPairGenerator.genKeyPair()
private fun buildKeyPair():KeyPair
val keySize = 2048
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(keySize)
return keyPairGenerator.genKeyPair()
//generators
fun fromKeyPair(name :String, keyPair: KeyPair):Person = Person(name, keyPair)
fun fromPublicKey(name :String, publicKey: PublicKey):Person = Person(name,KeyPair(publicKey,null))
fun fromPrivateKey(name :String, privateKey: PrivateKey):Person
//attempt to find the correct public key
if(privateKey !is RSAPrivateCrtKey)
error("Private key is not a RSAPrivateCrtKey and does not contain enough data to compute the public key")
val spec = RSAPublicKeySpec(privateKey.modulus,privateKey.publicExponent)
val factory = KeyFactory.getInstance("RSA")
val publicKey = factory.generatePublic(spec)
return Person(name, KeyPair(publicKey,privateKey))
fun deterministicFromName(name :String) :Person = Person(name,buildKeyPair(DigestUtils.sha1(name)!!.contentHashCode().toLong()))
fun generateNew(name :String) :Person = Person(name, buildKeyPair())
This also uses these classes:
class Signature(val byteArray: ByteArray)
override fun equals(other: Any?): Boolean
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Signature
if (!byteArray.contentEquals(other.byteArray)) return false
return true
override fun hashCode(): Int
return byteArray.contentHashCode()
and
class EncryptedData(val iv :ByteArray, val encryptedSecretKey :ByteArray,val encryptedData :ByteArray)
I'm using RSA keys to encrypt a randomly generated AES key, which can be used to encrypt data that is larger than 245 bytes.
The idea is that I can pass public keys around but treat everything as a Person
, and then throw an error if the private key is invalid. Is this a good design?
security cryptography kotlin
New contributor
$endgroup$
add a comment |
$begingroup$
I've written up a small wrapper for RSA and AES encryption in Kotlin, and I want to make sure I'm not making any glaring mistakes before use it. This is going on a small project with basically no needed security, but I wanted to try and write it correctly.
Here's my Person
class:
class Person private constructor(val name :String,
private val keyPair: KeyPair) {
val publicKey : PublicKey
get() = keyPair.public
private val privateKey : PrivateKey
get() = keyPair.private ?: error("Current Person implementation doesn't support functions that use the private key")
fun isValid() = fromPrivateKey(name,privateKey).publicKey == publicKey
override fun toString(): String
return "Person(name=$name, finger=$fingerprint().substring(0,10))"
fun sign(data :ByteArray): Signature
sig.initSign(privateKey)
sig.update(data)
return Signature(sig.sign())
fun fingerprint():String = DigestUtils.sha1Hex(publicKey.encoded)
/** This needs to be below 245 bytes */
fun encrypt(data :ByteArray, publicKey: PublicKey): ByteArray
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
return cipher.doFinal(data)
/** This needs to be below 245 bytes */
fun encrypt(data :ByteArray, person :Person):ByteArray = encrypt(data,person.publicKey)
/** This needs to be below 245 bytes */
fun decrypt(encrypted: ByteArray): ByteArray
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
return cipher.doFinal(encrypted)
/** This will encrypt over 245 bytes */
fun encryptAES(data :ByteArray,person :Person):EncryptedData = encryptAES(data,person.publicKey)
/** This will encrypt over 245 bytes */
fun encryptAES(data :ByteArray, publicKey : PublicKey): EncryptedData
val iv = ByteArray(16) -1
SecureRandom.getInstanceStrong().nextBytes(iv)
val keyGen = KeyGenerator.getInstance("AES")
keyGen.init(128)
val secretKey = keyGen.generateKey()
val ivParameterSpec = IvParameterSpec(iv)
val aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
val final = aesCipher.doFinal(data)
return EncryptedData(iv, encrypt(secretKey.encoded,publicKey), final)
//need to return encrypted secret key and the encrypted message
fun decryptAES(data : EncryptedData) :ByteArray
val iv = data.iv
val ivParameterSpec = IvParameterSpec(iv)
val decryptedSecretKey = decrypt(data.encryptedSecretKey)
val secretKey = SecretKeySpec(decryptedSecretKey, 0, decryptedSecretKey.size, "AES")
val aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
aesCipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
return aesCipher.doFinal(data.encryptedData)
And then I use the Companion object to make new instances of this class:
companion object
private val sig = java.security.Signature.getInstance("SHA1WithRSA")
fun verify(publicKey: PublicKey, signature: Signature, data: ByteArray): Boolean
sig.initVerify(publicKey)
sig.update(data)
return sig.verify(signature.byteArray)
//buildKeyPair(DigestUtils.sha1(name)!!.contentHashCode().toLong())
private fun buildKeyPair(seed :Long): KeyPair
val random = SecureRandom.getInstance("SHA1PRNG")
random.setSeed(seed)
val keySize = 2048
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(keySize,random)
return keyPairGenerator.genKeyPair()
private fun buildKeyPair():KeyPair
val keySize = 2048
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(keySize)
return keyPairGenerator.genKeyPair()
//generators
fun fromKeyPair(name :String, keyPair: KeyPair):Person = Person(name, keyPair)
fun fromPublicKey(name :String, publicKey: PublicKey):Person = Person(name,KeyPair(publicKey,null))
fun fromPrivateKey(name :String, privateKey: PrivateKey):Person
//attempt to find the correct public key
if(privateKey !is RSAPrivateCrtKey)
error("Private key is not a RSAPrivateCrtKey and does not contain enough data to compute the public key")
val spec = RSAPublicKeySpec(privateKey.modulus,privateKey.publicExponent)
val factory = KeyFactory.getInstance("RSA")
val publicKey = factory.generatePublic(spec)
return Person(name, KeyPair(publicKey,privateKey))
fun deterministicFromName(name :String) :Person = Person(name,buildKeyPair(DigestUtils.sha1(name)!!.contentHashCode().toLong()))
fun generateNew(name :String) :Person = Person(name, buildKeyPair())
This also uses these classes:
class Signature(val byteArray: ByteArray)
override fun equals(other: Any?): Boolean
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Signature
if (!byteArray.contentEquals(other.byteArray)) return false
return true
override fun hashCode(): Int
return byteArray.contentHashCode()
and
class EncryptedData(val iv :ByteArray, val encryptedSecretKey :ByteArray,val encryptedData :ByteArray)
I'm using RSA keys to encrypt a randomly generated AES key, which can be used to encrypt data that is larger than 245 bytes.
The idea is that I can pass public keys around but treat everything as a Person
, and then throw an error if the private key is invalid. Is this a good design?
security cryptography kotlin
New contributor
$endgroup$
I've written up a small wrapper for RSA and AES encryption in Kotlin, and I want to make sure I'm not making any glaring mistakes before use it. This is going on a small project with basically no needed security, but I wanted to try and write it correctly.
Here's my Person
class:
class Person private constructor(val name :String,
private val keyPair: KeyPair) {
val publicKey : PublicKey
get() = keyPair.public
private val privateKey : PrivateKey
get() = keyPair.private ?: error("Current Person implementation doesn't support functions that use the private key")
fun isValid() = fromPrivateKey(name,privateKey).publicKey == publicKey
override fun toString(): String
return "Person(name=$name, finger=$fingerprint().substring(0,10))"
fun sign(data :ByteArray): Signature
sig.initSign(privateKey)
sig.update(data)
return Signature(sig.sign())
fun fingerprint():String = DigestUtils.sha1Hex(publicKey.encoded)
/** This needs to be below 245 bytes */
fun encrypt(data :ByteArray, publicKey: PublicKey): ByteArray
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
return cipher.doFinal(data)
/** This needs to be below 245 bytes */
fun encrypt(data :ByteArray, person :Person):ByteArray = encrypt(data,person.publicKey)
/** This needs to be below 245 bytes */
fun decrypt(encrypted: ByteArray): ByteArray
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
return cipher.doFinal(encrypted)
/** This will encrypt over 245 bytes */
fun encryptAES(data :ByteArray,person :Person):EncryptedData = encryptAES(data,person.publicKey)
/** This will encrypt over 245 bytes */
fun encryptAES(data :ByteArray, publicKey : PublicKey): EncryptedData
val iv = ByteArray(16) -1
SecureRandom.getInstanceStrong().nextBytes(iv)
val keyGen = KeyGenerator.getInstance("AES")
keyGen.init(128)
val secretKey = keyGen.generateKey()
val ivParameterSpec = IvParameterSpec(iv)
val aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
val final = aesCipher.doFinal(data)
return EncryptedData(iv, encrypt(secretKey.encoded,publicKey), final)
//need to return encrypted secret key and the encrypted message
fun decryptAES(data : EncryptedData) :ByteArray
val iv = data.iv
val ivParameterSpec = IvParameterSpec(iv)
val decryptedSecretKey = decrypt(data.encryptedSecretKey)
val secretKey = SecretKeySpec(decryptedSecretKey, 0, decryptedSecretKey.size, "AES")
val aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
aesCipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
return aesCipher.doFinal(data.encryptedData)
And then I use the Companion object to make new instances of this class:
companion object
private val sig = java.security.Signature.getInstance("SHA1WithRSA")
fun verify(publicKey: PublicKey, signature: Signature, data: ByteArray): Boolean
sig.initVerify(publicKey)
sig.update(data)
return sig.verify(signature.byteArray)
//buildKeyPair(DigestUtils.sha1(name)!!.contentHashCode().toLong())
private fun buildKeyPair(seed :Long): KeyPair
val random = SecureRandom.getInstance("SHA1PRNG")
random.setSeed(seed)
val keySize = 2048
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(keySize,random)
return keyPairGenerator.genKeyPair()
private fun buildKeyPair():KeyPair
val keySize = 2048
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(keySize)
return keyPairGenerator.genKeyPair()
//generators
fun fromKeyPair(name :String, keyPair: KeyPair):Person = Person(name, keyPair)
fun fromPublicKey(name :String, publicKey: PublicKey):Person = Person(name,KeyPair(publicKey,null))
fun fromPrivateKey(name :String, privateKey: PrivateKey):Person
//attempt to find the correct public key
if(privateKey !is RSAPrivateCrtKey)
error("Private key is not a RSAPrivateCrtKey and does not contain enough data to compute the public key")
val spec = RSAPublicKeySpec(privateKey.modulus,privateKey.publicExponent)
val factory = KeyFactory.getInstance("RSA")
val publicKey = factory.generatePublic(spec)
return Person(name, KeyPair(publicKey,privateKey))
fun deterministicFromName(name :String) :Person = Person(name,buildKeyPair(DigestUtils.sha1(name)!!.contentHashCode().toLong()))
fun generateNew(name :String) :Person = Person(name, buildKeyPair())
This also uses these classes:
class Signature(val byteArray: ByteArray)
override fun equals(other: Any?): Boolean
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Signature
if (!byteArray.contentEquals(other.byteArray)) return false
return true
override fun hashCode(): Int
return byteArray.contentHashCode()
and
class EncryptedData(val iv :ByteArray, val encryptedSecretKey :ByteArray,val encryptedData :ByteArray)
I'm using RSA keys to encrypt a randomly generated AES key, which can be used to encrypt data that is larger than 245 bytes.
The idea is that I can pass public keys around but treat everything as a Person
, and then throw an error if the private key is invalid. Is this a good design?
security cryptography kotlin
security cryptography kotlin
New contributor
New contributor
edited 12 mins ago
Jamal♦
30.6k11121227
30.6k11121227
New contributor
asked 14 hours ago
Carson GrahamCarson Graham
62
62
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Carson Graham is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217401%2frsa-wrapper-written-in-kotlin%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Carson Graham is a new contributor. Be nice, and check out our Code of Conduct.
Carson Graham is a new contributor. Be nice, and check out our Code of Conduct.
Carson Graham is a new contributor. Be nice, and check out our Code of Conduct.
Carson Graham is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217401%2frsa-wrapper-written-in-kotlin%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown