RSA加解密Kotlin实现

下面是RSA的Kotlin实现

有个疑问的是:一般界面都是 128个字节限制,但是我用128个总是出错,看到说是要用256个,改成256后就没问题了,是不是我的Jdk版本的问题啊,我的IDEA是jdk10 然后Android studio用的jdk8 ,结果都是要用128的。jdk7就没测试了,有知道的告诉我。

object RSACrypt {
    val transformation = "RSA"
    val ENCRYPT_MAX_SIZE = 117
    val DECRYPT_MAX_SIZE = 256
    /**
     * 私钥加密
     */
    fun encryptByPrivateKey(str: String, privateKey: PrivateKey): String {
        val byteArray = str.toByteArray()
        val cipher = Cipher.getInstance(transformation)
        cipher.init(Cipher.ENCRYPT_MODE, privateKey)

        //定义缓冲区
        var temp: ByteArray? = null
        //当前偏移量
        var offset = 0

        val outputStream = ByteArrayOutputStream()

        while (byteArray.size - offset > 0) {
            //剩余的部分大于最大加密字段,则加密117个字节的最大长度
            if (byteArray.size - offset >= ENCRYPT_MAX_SIZE) {
                temp = cipher.doFinal(byteArray, offset, ENCRYPT_MAX_SIZE)
                //偏移量增加117
                offset += ENCRYPT_MAX_SIZE
            } else {
                //如果剩余的字节数小于117,则加密剩余的全部
                temp = cipher.doFinal(byteArray, offset, (byteArray.size - offset))
                offset = byteArray.size
            }
            outputStream.write(temp)
        }
        outputStream.close()
        return Base64.encode(outputStream.toByteArray())
    }

    /**
     * 公钥加密
     */
    fun encryptByPublicKey(str: String, publicKey: PublicKey): String {
        val byteArray = str.toByteArray()
        val cipher = Cipher.getInstance(transformation)
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)

        var temp: ByteArray? = null
        var offset = 0

        val outputStream = ByteArrayOutputStream()

        while (byteArray.size - offset > 0) {
            if (byteArray.size - offset >= ENCRYPT_MAX_SIZE) {
                temp = cipher.doFinal(byteArray, offset, ENCRYPT_MAX_SIZE)
                offset += ENCRYPT_MAX_SIZE
            } else {
                temp = cipher.doFinal(byteArray, offset, (byteArray.size - offset))
                offset = byteArray.size
            }
            outputStream.write(temp)
        }

        outputStream.close()
        return Base64.encode(outputStream.toByteArray())
    }

    /**
     * 私钥解密
     * 注意Exception in thread "main" javax.crypto.IllegalBlockSizeException:
     * Data must not be longer than 256 bytes
     * 关于到底是128个字节还是256个,我也很迷糊了,我写成128的时候就报这个错误,改成256后就没事了
     */
    fun decryptByPrivateKey(str: String, privateKey: PrivateKey): String {
        val byteArray = Base64.decode(str)
        val cipher = Cipher.getInstance(transformation)
        cipher.init(Cipher.DECRYPT_MODE, privateKey)

        //定义缓冲区
        var temp: ByteArray? = null
        //当前偏移量
        var offset = 0

        val outputStream = ByteArrayOutputStream()

        while (byteArray.size - offset > 0) {
            //剩余的部分大于最大解密字段,则加密限制的最大长度
            if (byteArray.size - offset >= DECRYPT_MAX_SIZE) {
                temp = cipher.doFinal(byteArray, offset, DECRYPT_MAX_SIZE)
                //偏移量增加128
                offset += DECRYPT_MAX_SIZE
            } else {
                //如果剩余的字节数小于最大长度,则解密剩余的全部
                temp = cipher.doFinal(byteArray, offset, (byteArray.size - offset))
                offset = byteArray.size
            }
            outputStream.write(temp)
        }
        outputStream.close()
        return String(outputStream.toByteArray())
    }

    /**
     * 公钥解密
     */
    fun decryptByPublicKey(str: String, publicKey: PublicKey): String {
        val byteArray = Base64.decode(str)
        val cipher = Cipher.getInstance(transformation)
        cipher.init(Cipher.DECRYPT_MODE, publicKey)

        var temp: ByteArray? = null
        var offset = 0

        val outputStream = ByteArrayOutputStream()

        while (byteArray.size - offset > 0) {
            if (byteArray.size - offset >= DECRYPT_MAX_SIZE) {
                temp = cipher.doFinal(byteArray, offset, DECRYPT_MAX_SIZE)
                offset += DECRYPT_MAX_SIZE
            } else {
                temp = cipher.doFinal(byteArray, offset, (byteArray.size - offset))
                offset = byteArray.size
            }
            outputStream.write(temp)
        }
        outputStream.close()
        return String(outputStream.toByteArray())
    }


}

fun main(args: Array) {
    /* val generator = KeyPairGenerator.getInstance("RSA")
     val genKeyPair = generator.genKeyPair()
     val privateKey = genKeyPair.private
     val publicKey = genKeyPair.public

     println("公钥:" + Base64.encode(publicKey.encoded))
     println("公钥Length:" + Base64.encode(publicKey.encoded).length)
     println("私钥:" + Base64.encode(privateKey.encoded))
     println("私钥Length:" + Base64.encode(privateKey.encoded).length)*/

    
    //秘钥对是一直变化的,不可能每次都生成
    val publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnvSR5VSoxCdhcgQzGkp8zSCOTUCP37YyVlJ8qzkRSxxNhB5OeKOP0OjhglAkn7v8i6SAR5ZDYwyLX6Y3W9+x5CoJ5bV3PpEzrq4qhv5JGBAE7q/ylR48y/3Aob/L04+4EuzFklzFILESmb7qsa5yKqtSO8Acvp2Ay0jJbzH6ZmhLkvW5C7+yoj/RnGWixop0EezxjV7wmI2aCHUAx4rUzbSoAhsonEYCRKS7MHx1t2M3vJBdinsnJEZ28tLXSdnTUrWzOK1gwYLfVW5ExQCLgOfGyweQ86ylgTDidjmeT4mpraqQHysLX/tv0FFhpUnxzK7P6DDWS3W0ep+o6eBvXQIDAQAB"
    val privateKeyStr = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCe9JHlVKjEJ2FyBDMaSnzNII5NQI/ftjJWUnyrORFLHE2EHk54o4/Q6OGCUCSfu/yLpIBHlkNjDItfpjdb37HkKgnltXc+kTOuriqG/kkYEATur/KVHjzL/cChv8vTj7gS7MWSXMUgsRKZvuqxrnIqq1I7wBy+nYDLSMlvMfpmaEuS9bkLv7KiP9GcZaLGinQR7PGNXvCYjZoIdQDHitTNtKgCGyicRgJEpLswfHW3Yze8kF2KeyckRnby0tdJ2dNStbM4rWDBgt9VbkTFAIuA58bLB5DzrKWBMOJ2OZ5PiamtqpAfKwtf+2/QUWGlSfHMrs/oMNZLdbR6n6jp4G9dAgMBAAECggEAekLTFPmQ9Y70vKXOSKKSa5Rm37SQ9RlGjm7TxT8XthYG6WAGK3Ri4eS9z2WlRddp4F6e7HD/U+gKK3/FhL0CLuTGyBBTr6QvhGQiAcMEpaVspcpfY6LmUGDVEZRcSlV419WWAYWpegO4stjN2+y5k2hC0AJsGZE7xyAtD4H5f1nvEbob0z/c9vlEYIUVZGsBf2PC7IPev64FLuGQE7/AsoM6jFh2etiCEkAbOUzHbhH3RAHajO7GdIPLBvFKGwYNKUh8lAKxQ11uZRjUQ2CgsawkgILV/DyqYoXJupsa0Q+ss0NVOkDf3tRbLc0fAmnpOjG78AgUIXNodOGzIEskYQKBgQDrFE8OV6k1rriW5O84kIxlU1J/jHl67C1R/fjrdZzJ7YzjqKwQo0GQhUiWyAJtoqGmMhaLgVi3VrbGUCPGJiaN/NuTPRWxGi/VXaJMPs+K2yErSyMEWmo6lcGjD2kOW7ZMUDoWMp3loNlliZPjMZ8Y3mZ3WeIv/vuxhpt+F0GgrwKBgQCtGfe7qLFxqZfpICebM4MV9tjWwr2q9boWFWuNg0DxTw0WyWQHQfNa+0afOIj6qMIxBJlvzV0Bet71XW5XKTmWbuQhYcbeoUcBBFB0DdM2Glret1A46KJOzxMz3HNAdkVhK028hr784DlE+Tg1SEWAYWidSlC9u80L49XPZgd7swKBgD7sMrT+Fda+q74IDVgwqMO+Z8ioSyPx77eQqX4s/wi1ww506YmSiUwrwOBLLQs3itk3cv1oY9y/IzE15j11nMBIvGVO5m1/Oup7o6OQ9HCQcvJprDfQE7sWtrv0tgQX3FXU65dheQ4r3cTl7GXVtGYtsXOk5Xw/XhOImjpH81MVAoGAQgIX/OB8Icq5GfXgBIflIdgKogKKzwl7F3a9l64IcrxhUmIjmbzlbrlJGeg2G9eEjaqiVAbsw2a2ZLxnGienRR0uMyiU7Ep1yAZ8I3UuKIBuTGV82uajFghS20DiVh+Dn2Ui9JQxej6KuCmM7IyNrEH44Zn4JhHaRAFyg+71RY8CgYEAmZVTkXFJXoIw8TAcV4968Uf/hfTwqWXc6uHAc/TAP4JNyi2+7TJ4xRziNenETcT9JByV8iw3iBjGwgeXr8BOzvPzs91foyG9elCK+WHBfT5XC9EssTwFXNTGdtcxG3fusHomwZlJnsuaHcBe0bX5HB0MXxJ3n4PjhvVQ+8qwuv0="

    val keyFactory = KeyFactory.getInstance("RSA")
    val privateKey = keyFactory.generatePrivate(PKCS8EncodedKeySpec(Base64.decode(privateKeyStr)))
    val publicKey = keyFactory.generatePublic(X509EncodedKeySpec(Base64.decode(publicKeyStr)))


    //注意:加密长度不能超过117个字节
    //注意:解密长度不能超过256个字节

    val str = "我喜欢编程,我喜欢编程,我喜欢编程,我喜欢编程,我喜欢编程我喜欢编程我喜欢编程我喜欢编程," +
            "我喜欢编程,我喜欢编程我喜欢编程我喜欢编程我喜欢编" + "我喜欢编程,我喜欢编程我喜欢编程我喜欢编程我喜欢编" +
            "我喜欢编程,我喜欢编程我喜欢编程我喜欢编程我喜欢编" + "我喜欢编程,我喜欢编程我喜欢编程我喜欢编程我喜欢编"
    println("加密的字段长度:" + str.length)
    println("加密的字段字节长度:" + str.toByteArray().size)


    val privateEnStartTime = System.currentTimeMillis()
    val encyptByPrivateKey = RSACrypt.encryptByPrivateKey(str, privateKey)
    println("私钥加密结果:$encyptByPrivateKey")
    println("私钥加密时间:${System.currentTimeMillis() - privateEnStartTime}")

    val publicDeStartTime = System.currentTimeMillis()
    val decryptByPublicKey = RSACrypt.decryptByPublicKey(encyptByPrivateKey, publicKey)
    println("公钥解密:$decryptByPublicKey")
    println("公钥解密时间:${System.currentTimeMillis() - publicDeStartTime}")


    val publicEnStartTime = System.currentTimeMillis()
    val encyptByPublicKey = RSACrypt.encryptByPublicKey(str, publicKey)
    println("公钥加密结果:$encyptByPublicKey")
    println("公钥加密时间:${System.currentTimeMillis() - publicEnStartTime}")


    val privateDeStartTime = System.currentTimeMillis()
    val decryptByPrivateKey = RSACrypt.decryptByPrivateKey(encyptByPublicKey, privateKey)
    println("私钥解密:$decryptByPrivateKey")
    println("私钥解密时间:${System.currentTimeMillis() - privateDeStartTime}")
}
运行结果.png

由图可以看出来:

  • RSA的公钥要短于私钥
  • RSA的公钥加解密都要快于私钥加解密

你可能感兴趣的:(RSA加解密Kotlin实现)