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;








1












$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?










share|improve this question









New contributor




Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$


















    1












    $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?










    share|improve this question









    New contributor




    Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$














      1












      1








      1





      $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?










      share|improve this question









      New contributor




      Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $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






      share|improve this question









      New contributor




      Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 12 mins ago









      Jamal

      30.6k11121227




      30.6k11121227






      New contributor




      Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 14 hours ago









      Carson GrahamCarson Graham

      62




      62




      New contributor




      Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Carson Graham is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















          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.









          draft saved

          draft discarded


















          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.









          draft saved

          draft discarded


















          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

          Prove that NP is closed under karp reduction?Space(n) not closed under Karp reductions - what about NTime(n)?Class P is closed under rotation?Prove or disprove that $NL$ is closed under polynomial many-one reductions$mathbfNC_2$ is closed under log-space reductionOn Karp reductionwhen can I know if a class (complexity) is closed under reduction (cook/karp)Check if class $PSPACE$ is closed under polyonomially space reductionIs NPSPACE also closed under polynomial-time reduction and under log-space reduction?Prove PSPACE is closed under complement?Prove PSPACE is closed under union?

          Is my guitar’s action too high? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Strings too stiff on a recently purchased acoustic guitar | Cort AD880CEIs the action of my guitar really high?Μy little finger is too weak to play guitarWith guitar, how long should I give my fingers to strengthen / callous?When playing a fret the guitar sounds mutedPlaying (Barre) chords up the guitar neckI think my guitar strings are wound too tight and I can't play barre chordsF barre chord on an SG guitarHow to find to the right strings of a barre chord by feel?High action on higher fret on my steel acoustic guitar