Kotlin學習筆記——加密解密

對稱加密:凱撒加密(位移),DES,AES

非對稱加密:RSA

消息摘要:md5,sha1,sha256,數字簽名


1.with高階函數,可以接收一個對象作爲參數,方法體裏對參數對象進行操作,最後一行可以返回結果,再用參數接收。

2.凱撒加密 :把字母移動一個數字來實現的加密和界面。

3.對稱加密


注意:中文DES加密後亂碼,因爲加密後的二進制數據在碼錶中找不到對應的字符,就會變成亂碼,所以加密後再用Base64進行加密,Base64會在碼錶將每個字節找到對應的字符。解密時,先用Base64解密,再用DES解密。

4.DES和AES密鑰長度 (8個字節,16個字節)

DES(56) 8Byte*8Bit=64位,最後一個字節是校驗符,所以需要56Bit

AES(128) 16Byte*8Bit = 128位

5.算法/工作模式/填充模式




注意://CBC工作模式需要三個參數 IvParameterSpec

cipher.init(Cipher.ENCRYPT_MODE, key,IvParameterSpec(password.toByteArray()))

6.應用場景:android緩存到本地的數據加密

可逆的,可以使用對稱加密(或者非對稱RSA)

DES和AES: 優先使用AES, 安全係數更高

7.非對稱加密


爲什麼要互換公鑰???這樣雙方纔可以交流吧,


8.如何生成RSA密鑰對

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

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

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

9.RSA非對稱加密, 示例:

import java.io.ByteArrayOutputStream
import java.security.KeyPairGenerator
import java.security.PrivateKey
import java.security.PublicKey
import java.util.*
import javax.crypto.Cipher


/**
 * 非對稱加密RSA加密和解密
 */
object RSACrypt {
    private val transformation = "RSA"
    private val ENCRYPT_MAX_SIZE = 117 //加密:每次最大加密長度117個字節
    private val DECRYPT_MAX_SIZE = 128 //解密:每次最大解密長度128個字節

    /**
     * 私鑰加密
     */
    fun encryptByPrivateKey(input: String, privateKey: PrivateKey): String {
        /********************非對稱加/解密三部曲**********************/
        //1.創建cipher對象
        val cipher = Cipher.getInstance(transformation)
        //2.初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE, privateKey)
        //3.加密/解密
        val encrypt = cipher.doFinal(input.toByteArray())
        return Base64.getEncoder().encodeToString(encrypt)
    }

    /**
     * 公鑰解密
     */
    fun decryptByPublicKey(input: String, publicKey: PublicKey): String {
        val decode = Base64.getDecoder().decode(input)
        /********************非對稱加/解密三部曲**********************/
        //1.創建cipher對象
        val cipher = Cipher.getInstance(transformation)
        //2.初始化cipher
        cipher.init(Cipher.DECRYPT_MODE, publicKey)
        //3.加密/解密
        val encrypt = cipher.doFinal(decode)
        return String(encrypt)
    }

    /**
     * 公鑰加密
     */
    fun encryptByPublicKey(input: String, publicKey: PublicKey): String {
        /********************非對稱加/解密三部曲**********************/
        //1.創建cipher對象
        val cipher = Cipher.getInstance(transformation)
        //2.初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)
        //3.加密/解密
        val encrypt = cipher.doFinal(input.toByteArray())
        return Base64.getEncoder().encodeToString(encrypt)
    }

    /**
     * 私鑰解密
     */
    fun decryptByPrivateKey(input: String, privateKey: PrivateKey): String {
        val decode = Base64.getDecoder().decode(input)
        /********************非對稱加/解密三部曲**********************/
        //1.創建cipher對象
        val cipher = Cipher.getInstance(transformation)
        //2.初始化cipher
        cipher.init(Cipher.DECRYPT_MODE, privateKey)
        //3.加密/解密
        val encrypt = cipher.doFinal(decode)
        return String(encrypt)
    }

    /**
     * 私鑰分段加密
     */
    fun encryptByPrivateKey2(input: String, privateKey: PrivateKey): String {
        val byteArray = input.toByteArray()

        var temp:ByteArray
        var offset = 0 //當前偏移的位置

        val bos = ByteArrayOutputStream()

        /********************非對稱加/解密三部曲**********************/
        //1.創建cipher對象
        val cipher = Cipher.getInstance(transformation)
        //2.初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE, privateKey)
        //3.加密:分段加密
//        val encrypt = cipher.doFinal()

        while (byteArray.size - offset >0) { //沒有加密完
            //每次最大加密117個字節
            if(byteArray.size - offset >= ENCRYPT_MAX_SIZE){
                //剩餘部分大於117,加密完整117
                temp  = cipher.doFinal(byteArray, offset, ENCRYPT_MAX_SIZE)
                offset+= ENCRYPT_MAX_SIZE
            }else{
                //加密最後一塊
                temp  = cipher.doFinal(byteArray, offset, byteArray.size - offset)
                offset = byteArray.size
            }
            //存儲到臨時緩衝區
            bos.write(temp)
        }
        bos.close()

        return Base64.getEncoder().encodeToString(bos.toByteArray())
    }

    /**
     * 公鑰分段解密
     */
    fun decryptByPublicKeyKey2(input: String, publicKey: PublicKey): String? {
        val byteArray = Base64.getDecoder().decode(input)

        var temp:ByteArray
        var offset = 0 //當前偏移的位置

        val bos = ByteArrayOutputStream()

        /********************非對稱加/解密三部曲**********************/
        //1.創建cipher對象
        val cipher = Cipher.getInstance(transformation)
        //2.初始化cipher
        cipher.init(Cipher.DECRYPT_MODE, publicKey)
        //3.加密:分段加密
//        val encrypt = cipher.doFinal()

        while (byteArray.size - offset >0) { //沒有加密完
            //每次最大解密128個字節
            if(byteArray.size - offset >= DECRYPT_MAX_SIZE){
                //剩餘部分大於128,解密完整128
                temp  = cipher.doFinal(byteArray, offset, DECRYPT_MAX_SIZE)
                offset+= DECRYPT_MAX_SIZE
            }else{
                //解密最後一塊
                temp  = cipher.doFinal(byteArray, offset, byteArray.size - offset)
                offset = byteArray.size
            }
            //存儲到臨時緩衝區
            bos.write(temp)
        }
        bos.close()

        return String(bos.toByteArray())
    }

    /**
     * 公鑰分段加密
     */
    fun encryptByPublicKey2(input: String, publicKey: PublicKey): String {
        val byteArray = input.toByteArray()

        var temp:ByteArray
        var offset = 0 //當前偏移的位置

        val bos = ByteArrayOutputStream()

        /********************非對稱加/解密三部曲**********************/
        //1.創建cipher對象
        val cipher = Cipher.getInstance(transformation)
        //2.初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)
        //3.加密:分段加密
//        val encrypt = cipher.doFinal()

        while (byteArray.size - offset >0) { //沒有加密完
            //每次最大加密117個字節
            if(byteArray.size - offset >= ENCRYPT_MAX_SIZE){
                //剩餘部分大於117,加密完整117
                temp  = cipher.doFinal(byteArray, offset, ENCRYPT_MAX_SIZE)
                offset+= ENCRYPT_MAX_SIZE
            }else{
                //加密最後一塊
                temp  = cipher.doFinal(byteArray, offset, byteArray.size - offset)
                offset = byteArray.size
            }
            //存儲到臨時緩衝區
            bos.write(temp)
        }
        bos.close()

        return Base64.getEncoder().encodeToString(bos.toByteArray())
    }

    /**
     * 私鑰分段解密
     */
    fun decryptByPrivateKey2(input: String, privateKey: PrivateKey): String? {
        val byteArray = Base64.getDecoder().decode(input)

        var temp:ByteArray
        var offset = 0 //當前偏移的位置

        val bos = ByteArrayOutputStream()

        /********************非對稱加/解密三部曲**********************/
        //1.創建cipher對象
        val cipher = Cipher.getInstance(transformation)
        //2.初始化cipher
        cipher.init(Cipher.DECRYPT_MODE, privateKey)
        //3.加密:分段加密
//        val encrypt = cipher.doFinal()

        while (byteArray.size - offset >0) { //沒有解密完
            //每次最大解密128個字節
            if(byteArray.size - offset >= DECRYPT_MAX_SIZE){
                //剩餘部分大於128,解密完整128
                temp  = cipher.doFinal(byteArray, offset, DECRYPT_MAX_SIZE)
                offset+= DECRYPT_MAX_SIZE
            }else{
                //解密最後一塊
                temp  = cipher.doFinal(byteArray, offset, byteArray.size - offset)
                offset = byteArray.size
            }
            //存儲到臨時緩衝區
            bos.write(temp)
        }
        bos.close()

        return String(bos.toByteArray())
    }
}

fun main(args: Array<String>) {
    //如何生成密鑰對
    val generator = KeyPairGenerator.getInstance("RSA")
    val keyPair = generator.genKeyPair()//生成密鑰對
    val publicKey = keyPair.public//公鑰
    val privateKey = keyPair.private//私鑰

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

    var input_short = "黑馬"
    //    私鑰加密
    val encryptByPrivateKey = RSACrypt.encryptByPrivateKey(input_short, privateKey)
    println("私鑰加密=" + encryptByPrivateKey)
    //   公鑰解密
    val decryptByPublicKey = RSACrypt.decryptByPublicKey(encryptByPrivateKey, publicKey)
    println("公鑰解密=" + decryptByPublicKey)

    //    公鑰加密
    val encryptByPublicKey = RSACrypt.encryptByPublicKey(input_short, publicKey)
    println("公鑰加密=" + encryptByPublicKey)
    //    私鑰解密
    val decryptByPrivateKey = RSACrypt.decryptByPrivateKey(encryptByPublicKey, privateKey)
    println("私鑰解密=" + decryptByPrivateKey)


    var input_long = "黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬黑馬"
    //    私鑰分段加密
    val encryptByPrivateKey2 = RSACrypt.encryptByPrivateKey2(input_long, privateKey)
    println("私鑰分段加密=" + encryptByPrivateKey2)
    //     公鑰分段解密
    val decryptByPublicKeyKey2 = RSACrypt.decryptByPublicKeyKey2(encryptByPrivateKey2, publicKey)
    println("公鑰分段解密=" + decryptByPublicKeyKey2)

    //    公鑰分段加密
    val encryptByPublicKey2 = RSACrypt.encryptByPublicKey2(input_long, publicKey)
    println("公鑰分段加密=" + encryptByPublicKey2)
    //    私鑰分段解密
    val decryptByPrivateKey2 = RSACrypt.decryptByPrivateKey2(encryptByPublicKey2, privateKey)
    println("私鑰分段解密=" + decryptByPrivateKey2)
    
}

10.非對稱加密RSA-分段加密,分段解密

注意:

  1. RSA速度很慢,所以加密的長度不能超過117個字節,所以可以採取分段加密
  2. 分段解密是,每次最大解密128字節



11.RSA保存密鑰對

開發中先會將生成的密鑰對保存成字符串,使用時將字符串轉成對象。

注意:私鑰通常的加密方式是:PKCS8; 公鑰通常的加密方式是:X509。

    /***********************保存密鑰對********************************/
    val  publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpOATXST66dBJzkgYRMXqlIfjSAlkNaKcin4bjkuj3fUEQTHBPqkAhf9UbcoeT59/V2U5xjH3JX5SnDe7zDo2TT0YxIu402zaimbY52uZzbgsmS3+6jhX6URwcQIPghXEDrKIFwWEBWWV9+leRilBCS9sGQk8Cxq/C9wLwHKJ+3wIDAQAB"
    val  privateKeyStr = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOk4BNdJPrp0EnOSBhExeqUh+NICWQ1opyKfhuOS6Pd9QRBMcE+qQCF/1Rtyh5Pn39XZTnGMfclflKcN7vMOjZNPRjEi7jTbNqKZtjna5nNuCyZLf7qOFfpRHBxAg+CFcQOsogXBYQFZZX36V5GKUEJL2wZCTwLGr8L3AvAcon7fAgMBAAECgYEAuTwiNDBb31IT2bFQmlVXWVNrQrpUqt7FaS2VwKlN2kyk4eIkjlHmD/VteRh1cNeJpFut/2gb/FarRig98tVLQgIRJkHqatPyw+uBJPvudTuo2VyRD+p2Riqx/iFtCk9ArBViBWa/yn8bWncC+Wx5iLodHM1YLNSUvbemGYJ/TykCQQD+JYPD+qeRJ1F+fYAxa9Q1/qkVD5dJQscioxELDDVH6F9UoSXyKkaA3pmQiDnHNf/5YKUHE+EfMgYOM2tHh9fzAkEA6utuw3zwddPjOH+d4mnKoU9JQZSNvMkV1emW8Zos45FUneN65FI4e7G8UIYlJyzxGiHwTO+l7ULMYng8ucuEZQJAT9CsTxIbKgT1HQqBBgRdQw/VPh4FXyavr3sS0StmWEzsE4IAjsskFTjTdYayzpNw7nqhmVVu8AMfz7nqSS6qbQJBAL1VywvboqIUiEl88W8N/LZOBKjKZgIFv4eMoI9Qx2USOLSYJu/mJIftE+2CcGdGnXuGZvpbG8xBziB+79J+6NECQCEH4tHy51c0lbg3XCfLGC3nyByYPFleflx714xFlQYAasPL/CXRyjSH9oJAHuD+CMI6Av/YNMwnjNaubyqlyOE="

    val keyFactory:KeyFactory = KeyFactory.getInstance("RSA")
    val privateKey:PrivateKey = keyFactory.generatePrivate(PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyStr)))//私鑰
    val publicKey:PublicKey = keyFactory.generatePublic(X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyStr)))//公鑰
12.總結


13.消息摘要


消息摘要需要注意的:


消息摘要應用場景:一般不可逆的,都用消息摘要


下圖中的登錄接口,密碼是明文登錄,容易被抓包,不安全,一般會採用md5加密,爲了增加破解難度,會多次加密,同時再結果後加鹽(就是拼接自定義字符串)


14.數字簽名



15.數字簽名流程圖



16.加密算法總結







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章