kotlin版本RSA非對(duì)稱(chēng)加密解密與分段加密解密

基于kotlin語(yǔ)言的RSA非對(duì)稱(chēng)加密解密與分段加密解密

RSA非對(duì)稱(chēng)加密

RSA非對(duì)稱(chēng)加密的具體算法與來(lái)源我就不寫(xiě)了糊肤,感興趣的可以自己找度娘或者維基百科
前面我的兩篇文章講了DES和AES對(duì)稱(chēng)加密横侦,我們可以看出他們加密和解密時(shí)都使用的是同一個(gè)密鑰邮丰,那么:
非對(duì)稱(chēng)加密就是加密和解密使用不同的密鑰:
我們將它稱(chēng)為密鑰對(duì),密鑰對(duì)包含公鑰私鑰兩個(gè),如果使用公鑰加密則要使用私鑰解密,反之使用私鑰加密則要用公鑰解密耿眉,我們將相對(duì)應(yīng)的公鑰私鑰稱(chēng)為密鑰對(duì)。
密鑰對(duì)由系統(tǒng)生成
使用時(shí)兩個(gè)組織或者個(gè)人通過(guò)交換公鑰解密

缺點(diǎn)

RSA非對(duì)稱(chēng)加密速度慢鱼响,如果文件較大加密時(shí)間會(huì)較長(zhǎng)而且需要使用分段加密

首先生成密鑰對(duì)

注意自己生成的密鑰對(duì)的位數(shù)鸣剪,這個(gè)涉及到你加密解密時(shí)的最大位數(shù),我生成的是2048bits的热押,所以每次最大加密字節(jié)為245西傀,每次最大解密字節(jié)為256

    //如何生成密鑰對(duì):2048bit
    val generator = KeyPairGenerator.getInstance("RSA")//密鑰生成器
    val keyPair = generator.genKeyPair()//生成密鑰對(duì)
    val publicKey = keyPair.public//公鑰
    val privateKey = keyPair.private//私鑰

    println("publicKey="+Base64.getEncoder().encodeToString(publicKey.encoded))
    println("privateKey="+Base64.getEncoder().encodeToString(privateKey.encoded))

注意打印的寫(xiě)法,如果直接打印你看到的是三個(gè)參數(shù)桶癣,這樣會(huì)打印出你的公鑰和私鑰方便我們保存拥褂,否則每次都會(huì)生成新的密鑰對(duì)。

保存密鑰對(duì)

首先我們將第一次生成的公鑰和私鑰打印出來(lái),然后保存

val publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAivLe1hpft8xOgdEyYTllA04dj+0ILZXTSkugcBKdChr15mk7KchD4D2RkBGUl5SL17oPVBYstLJnEbf1oBmHnkb7xm8A0VDoJJKHwgFLiS7QlLSr+Lta3fePopswuExgt3JFcRlv84RVqz0W5H2p2kiR063+Cw06BwY8496M/M8h5EoZoNkCKEmQPR3fP2Y0bpeZhVyTwLIKyhtjgMA68qSVJeiDYADbADNK/plZG5FDUspa27Rhlm4HYR5gFJKyIUmylE1EmMj67hJ+hHhP8qbK60S21IIwPhiRLISMrLkV3IqVGQk/hiW0VOUlYaPZ6ylwCQEwuKZS7cbHIDI5jwIDAQAB"
val privateKeyString = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCK8t7WGl+3zE6B0TJhOWUDTh2P7QgtldNKS6BwEp0KGvXmaTspyEPgPZGQEZSXlIvXug9UFiy0smcRt/WgGYeeRvvGbwDRUOgkkofCAUuJLtCUtKv4u1rd94+imzC4TGC3ckVxGW/zhFWrPRbkfanaSJHTrf4LDToHBjzj3oz8zyHkShmg2QIoSZA9Hd8/ZjRul5mFXJPAsgrKG2OAwDrypJUl6INgANsAM0r+mVkbkUNSylrbtGGWbgdhHmAUkrIhSbKUTUSYyPruEn6EeE/ypsrrRLbUgjA+GJEshIysuRXcipUZCT+GJbRU5SVho9nrKXAJATC4plLtxscgMjmPAgMBAAECggEAX8E35/yM8jEN+VCdk3rmLfzrSoBjHmceERlFG3b4WjpyM7NZXlXw0NwdMFetOzjXlndWkPAnJu+7L+7Ciu6NE3p/kCR3P8it8mY4wG38DDIC9Df+O4+B823jwn+Id7nK/SD20hZhnEQadcPHvvcK0q8oL+S8KgmXb7fQxohcSOu4lk2z6POuIXTlBIMYEJI7ASb1A4XNyM8ScOROLp3RYEZUTU/b4/MuA/sEiYN1+yeK6NhK0mut621gyu1joLQBivHOw+lV6+fHS6j8hMeWKXFYEXIOvTXNhUu3XSQLt95V9NF8XwyzA1iX1Tn/+a6YGuma+nIHpWYkM7u9hnZeAQKBgQD1/cBsdbjHj9gUOQAdIz1MJQ2gA8FWdrlE6ZEpQWg8IvgAK1Lpc3/FfO74QqREsFYpDZPKFtfSOhrM3vJq5RK5fInfZmSG3ZopVvRUKwT8w65fslCQxQmgqG+V6Tk7b74x1UuJi2pYi9EgS+pGQNbJh+bzNYt5qERk2Q43maVsTwKBgQCQmimTdwmEDJ/4+zSEwktCXsuITxkLR8SEIDZvA3Ed87P+I03Vqwe0aM099nnmjzREML54CkWaC26dvwNzDcPAJgi1bDa5waKRit9ze3WTV47G8PpQjbu/eZWAcFNzuWW85k5Afc/F/Q2peS2J7NHzhD03fe6MyD/09n+NxGzOwQKBgDSA6KU9qybNCO2oDOIrN1YdQn84zfdKd9jBkX4gu8K6I/zFQnkZcdgRBmBuuOkASiORBk5H+eChDj9UBqHSKuD0N+k6zZILkm/oY1XjqLjae0lpodCEfb2QteBlWxXYj9vLDshYvWYQ0Z33FhXQmQeCvkSC1TYuOAreWS582NX5AoGARYtPGZPzaKWlvloaTQsgpN/wZTMdaVZvxde0NjniijQtybjy8yMZRoPsybMjt2YCDhWfVR4jkU2UOpumLgxdq6jfIVnVDAt7gyHWC7VBu8YtbbJxwJIZzKHN7AKZsBtnOa1Nzyhy59anXm1gIGhcJRDhXDHdq6mXUNnISMdCSUECgYAvWqSPlTocztnl1cxAkbmrB96Y4/mKCbN63/8RfaaF+HTOLONhshN5E3H7YJVVP83uif9/y+Ey7g7dWqn7D+dZGv6FHM3+T1npmYtTQZ4U9QUPN/KGPItnYbQhcqiqjRKYCqLU26qipaq8Mb6oqcwaKCm7uE7BywGYS8yYrQKwoQ=="

然后我們將字符串轉(zhuǎn)為密鑰對(duì)對(duì)象

//字符串轉(zhuǎn)成密鑰對(duì)對(duì)象
    val keyFactory = KeyFactory.getInstance("RSA")
    val privateKey = keyFactory.generatePrivate(PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyString)))
    val publicKey = keyFactory.generatePublic(X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyString)))

后面我們就可以使用生成的密鑰對(duì)

加密

首先我們將創(chuàng)建cipher需要的內(nèi)容定義好

val transformation = "RSA"

私鑰加密

    /**
     * 私鑰加密
     * @param input 原文
     * @param privateKey 私鑰
     */
    fun encryptByPrivateKey(input:String,privateKey:PrivateKey): String {

        //****非對(duì)稱(chēng)加密****
        //創(chuàng)建cipher對(duì)象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE,privateKey)
        //加密
        val encrypt = cipher.doFinal(input.toByteArray())

        return String(Base64.getEncoder().encode(encrypt))

    }

公鑰加密

    /**
     * 公鑰加密
     * @param input 原文
     * @param publicKey 公鑰
     */
    fun encryptByPublicKey(input:String,publicKey:PublicKey): String {

        //****非對(duì)稱(chēng)加密****
        //創(chuàng)建cipher對(duì)象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE,publicKey)
        //加密
        val encrypt = cipher.doFinal(input.toByteArray())

        return String(Base64.getEncoder().encode(encrypt))

    }

然后我們?cè)趍ain函數(shù)中調(diào)用牙寞,并打印結(jié)果

    val desInput = "測(cè)試"
    //私鑰加密
    val byPrivateKey = RSACrypt.encryptByPrivateKey(desInput, privateKey)
    println("RSA私鑰加密結(jié)果:"+byPrivateKey)
    //公鑰加密
    val byPublicKey = RSACrypt.encryptByPublicKey(desInput, publicKey)
    println("RSA公鑰加密結(jié)果:"+byPublicKey)

接下來(lái)我們進(jìn)行解密

解密

當(dāng)我們進(jìn)行解密時(shí)會(huì)發(fā)現(xiàn)報(bào)錯(cuò)饺鹃,錯(cuò)誤如下

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:346)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
    at javax.crypto.Cipher.doFinal(Cipher.java:2168)
    at RSACrypt.decryptByPrivateKey(RSACrypt.kt:51)
    at RSACryptKt.main(RSACrypt.kt:306)

通過(guò)錯(cuò)誤提示我們可以知道,解密數(shù)據(jù)不能超過(guò)256字節(jié)间雀。但是我們加密后的秘文超過(guò)了256字節(jié)悔详,那么我們應(yīng)該怎么解決呢:
方式為分段解密,那我們我們可以試試如果加密的字段過(guò)長(zhǎng)的話也會(huì)報(bào)錯(cuò)惹挟,這里我就不打印了茄螃,想嘗試的可以自己試試。
加密時(shí)如果超過(guò)245字節(jié)就會(huì)報(bào)錯(cuò)连锯,解決方法同樣是使用分段加密归苍。

分段加密

分段加密和分擔(dān)解密的思路其實(shí)很簡(jiǎn)單就是將我們輸入的字節(jié)進(jìn)行分段,然后進(jìn)行加密解密运怖。很簡(jiǎn)單的思路所以我就不詳細(xì)解釋了拼弃,在代碼中都有注釋。
首先我們將加密的最大字節(jié)數(shù)與解密的最大字節(jié)數(shù)設(shè)為常量

    //注意自己生成的密鑰對(duì)的bits長(zhǎng)度
    val ENCRYPT_MAX_SIZE = 245//加密每次最大加密字節(jié)
    val DECRYPT_MAX_SIZE = 256//解密每次最大加密字節(jié)

私鑰分段加密

    /**
     * 私鑰分段加密
     * @param input 原文
     * @param privateKey 私鑰
     */
    fun segmentEncryptByPrivateKey(input:String,privateKey:PrivateKey): String {

        //創(chuàng)建cipher對(duì)象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE,privateKey)

        //****非對(duì)稱(chēng)加密****
        val byteArray = input.toByteArray()

        //分段加密
        var temp:ByteArray? = null
        var offset = 0 //當(dāng)前偏移的位置

        val outputStream = ByteArrayOutputStream()

        //拆分input
        while (byteArray.size - offset > 0){
            //每次最大加密245個(gè)字節(jié)
            if (byteArray.size - offset >= ENCRYPT_MAX_SIZE){
                //剩余部分大于245
                //加密完整245
                temp = cipher.doFinal(byteArray,offset, ENCRYPT_MAX_SIZE)
                //重新計(jì)算偏移位置
                offset += ENCRYPT_MAX_SIZE
            }else{
                //加密最后一塊
                temp = cipher.doFinal(byteArray,offset, byteArray.size - offset)
                //重新計(jì)算偏移位置
                offset = byteArray.size
            }
            //存儲(chǔ)到臨時(shí)的緩沖區(qū)
            outputStream.write(temp)
        }
        outputStream.close()

        return String(Base64.getEncoder().encode(outputStream.toByteArray()))

    }

公鑰分段加密

    /**
     * 公鑰分段加密
     * @param input 原文
     * @param publicKey 公鑰
     */
    fun segmentEncryptByPublicKey(input:String,publicKey:PublicKey): String {

        //創(chuàng)建cipher對(duì)象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE,publicKey)
        //加密
//        val encrypt = cipher.doFinal(input.toByteArray())

        //****非對(duì)稱(chēng)加密****
        val byteArray = input.toByteArray()

        var temp:ByteArray? = null
        var offset = 0 //當(dāng)前偏移的位置

        val outputStream = ByteArrayOutputStream()

        //拆分input
        while (byteArray.size - offset > 0){
            //每次最大加密117個(gè)字節(jié)
            if (byteArray.size - offset >= ENCRYPT_MAX_SIZE){
                //剩余部分大于117
                //加密完整117
                temp = cipher.doFinal(byteArray,offset, ENCRYPT_MAX_SIZE)
                //重新計(jì)算偏移位置
                offset += ENCRYPT_MAX_SIZE
            }else{
                //加密最后一塊
                temp = cipher.doFinal(byteArray,offset, byteArray.size - offset)
                //重新計(jì)算偏移位置
                offset = byteArray.size
            }
            //存儲(chǔ)到臨時(shí)的緩沖區(qū)
            outputStream.write(temp)
        }
        outputStream.close()

        return String(Base64.getEncoder().encode(outputStream.toByteArray()))

    }

這樣我們可以打印結(jié)果查看

    val input = "RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試RSA加密測(cè)試"
    // 超過(guò)245個(gè)字節(jié)需要使用分段加密
    //私鑰分段加密
    val encryptByPrivateKey = RSACrypt.segmentEncryptByPrivateKey(input, privateKey)
    println("RSA私鑰分段加密結(jié)果:"+encryptByPrivateKey)
    //公鑰分段加密
    val encryptByPublicKey = RSACrypt.segmentEncryptByPublicKey(input, publicKey)
    println("RSA公鑰分段加密結(jié)果:"+encryptByPublicKey)

分段解密

分段解密的原理一樣摇展,我們需要將加密后的秘文分段吻氧,然后解密

私鑰分段解密

    /**
     * 私鑰分段解密
     * @param input 秘文
     * @param privateKey 私鑰
     */
    fun segmentDecryptByPrivateKey(input:String,privateKey:PrivateKey): String {

        //創(chuàng)建cipher對(duì)象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.DECRYPT_MODE,privateKey)

        //****非對(duì)稱(chēng)加密****
        val byteArray = Base64.getDecoder().decode(input)

        //分段解密
        var temp:ByteArray? = null
        var offset = 0 //當(dāng)前偏移的位置

        val outputStream = ByteArrayOutputStream()

        //拆分input
        while (byteArray.size - offset > 0){
            //每次最大解密256個(gè)字節(jié)
            if (byteArray.size - offset >= DECRYPT_MAX_SIZE){

                temp = cipher.doFinal(byteArray,offset, DECRYPT_MAX_SIZE)
                //重新計(jì)算偏移位置
                offset += DECRYPT_MAX_SIZE
            }else{
                //加密最后一塊
                temp = cipher.doFinal(byteArray,offset, byteArray.size - offset)
                //重新計(jì)算偏移位置
                offset = byteArray.size
            }
            //存儲(chǔ)到臨時(shí)的緩沖區(qū)
            outputStream.write(temp)
        }
        outputStream.close()

        return String(outputStream.toByteArray())

    }

公鑰分段解密

    /**
     * 公鑰分段解密
     * @param input 秘文
     * @param privateKey 公鑰
     */
    fun segmentDecryptByPublicKey(input:String,publicKey: PublicKey): String {

        //創(chuàng)建cipher對(duì)象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.DECRYPT_MODE,publicKey)

        //****非對(duì)稱(chēng)加密****
        val byteArray = Base64.getDecoder().decode(input)

        //分段解密
        var temp:ByteArray? = null
        var offset = 0 //當(dāng)前偏移的位置

        val outputStream = ByteArrayOutputStream()

        //拆分input
        while (byteArray.size - offset > 0){
            //每次最大解密256個(gè)字節(jié)
            if (byteArray.size - offset >= DECRYPT_MAX_SIZE){

                temp = cipher.doFinal(byteArray,offset, DECRYPT_MAX_SIZE)
                //重新計(jì)算偏移位置
                offset += DECRYPT_MAX_SIZE
            }else{
                //加密最后一塊
                temp = cipher.doFinal(byteArray,offset, byteArray.size - offset)
                //重新計(jì)算偏移位置
                offset = byteArray.size
            }
            //存儲(chǔ)到臨時(shí)的緩沖區(qū)
            outputStream.write(temp)
        }
        outputStream.close()

        return String(outputStream.toByteArray())

    }

然后我們進(jìn)行結(jié)果打印,需要注意:
使用私鑰解密的是用公鑰加密的秘文
使用公鑰解密的是用私鑰加密的秘文

    //分段解密
    //私鑰分段解密:input應(yīng)該為使用公鑰加密后的秘文
    val decryptByPrivateKey = RSACrypt.segmentDecryptByPrivateKey(encryptByPublicKey, privateKey)
    println("RSA私鑰分段解密結(jié)果:"+decryptByPrivateKey)
    //公鑰分段解密:input應(yīng)該為使用私鑰加密后的秘文
    val decryptByPublicKey = RSACrypt.segmentDecryptByPublicKey(encryptByPrivateKey, publicKey)
    println("RSA公鑰分段解密結(jié)果:"+decryptByPublicKey)

以上就是RSA非對(duì)稱(chēng)加密解密的全部?jī)?nèi)容
RSA加密主要用于數(shù)字簽名咏连,SSL證書(shū)等用途
如果文中有錯(cuò)誤的地方盯孙,歡迎評(píng)論指出
謝謝觀看

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市祟滴,隨后出現(xiàn)的幾起案子镀梭,更是在濱河造成了極大的恐慌,老刑警劉巖踱启,帶你破解...
    沈念sama閱讀 222,865評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡埠偿,警方通過(guò)查閱死者的電腦和手機(jī)透罢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)冠蒋,“玉大人羽圃,你說(shuō)我怎么就攤上這事《督耍” “怎么了朽寞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,631評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)斩郎。 經(jīng)常有香客問(wèn)我脑融,道長(zhǎng),這世上最難降的妖魔是什么缩宜? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,199評(píng)論 1 300
  • 正文 為了忘掉前任肘迎,我火速辦了婚禮,結(jié)果婚禮上锻煌,老公的妹妹穿的比我還像新娘妓布。我一直安慰自己,他們只是感情好宋梧,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布匣沼。 她就那樣靜靜地躺著,像睡著了一般捂龄。 火紅的嫁衣襯著肌膚如雪释涛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,793評(píng)論 1 314
  • 那天跺讯,我揣著相機(jī)與錄音枢贿,去河邊找鬼。 笑死刀脏,一個(gè)胖子當(dāng)著我的面吹牛局荚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播愈污,決...
    沈念sama閱讀 41,221評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼耀态,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了暂雹?” 一聲冷哼從身側(cè)響起首装,我...
    開(kāi)封第一講書(shū)人閱讀 40,174評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎杭跪,沒(méi)想到半個(gè)月后仙逻,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體驰吓,經(jīng)...
    沈念sama閱讀 46,699評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評(píng)論 3 343
  • 正文 我和宋清朗相戀三年系奉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了檬贰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,918評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缺亮,死狀恐怖翁涤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情萌踱,我是刑警寧澤葵礼,帶...
    沈念sama閱讀 36,573評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站并鸵,受9級(jí)特大地震影響鸳粉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜能真,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評(píng)論 3 336
  • 文/蒙蒙 一赁严、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧粉铐,春花似錦疼约、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,749評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至汤踏,卻和暖如春织鲸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背溪胶。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,862評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工搂擦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哗脖。 一個(gè)月前我還...
    沈念sama閱讀 49,364評(píng)論 3 379
  • 正文 我出身青樓瀑踢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親才避。 傳聞我的和親對(duì)象是個(gè)殘疾皇子橱夭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容