Kotlin学习笔记——加密解密

对称加密:凯撒加密(位移),DES,AES

非对称加密:RSA

消息摘要:md5,sha1,sha256,数字签名


1.with高阶函数,可以接收一个对象作为参数,方法体里对参数对象进行操作,最后一行可以返回结果,再用参数接收。

2.凯撒加密 :把字母移动一个数字来实现的加密和界面。

3.对称加密

Kotlin学习笔记——加密解密_第1张图片

注意:中文DES加密后乱码,因为加密后的二进制数据在码表中找不到对应的字符,就会变成乱码,所以加密后再用Base64进行加密,Base64会在码表将每个字节找到对应的字符。解密时,先用Base64解密,再用DES解密。

4.DES和AES密钥长度 (8个字节,16个字节)

DES(56) 8Byte*8Bit=64位,最后一个字节是校验符,所以需要56Bit

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

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

Kotlin学习笔记——加密解密_第2张图片

Kotlin学习笔记——加密解密_第3张图片

Kotlin学习笔记——加密解密_第4张图片

注意://CBC工作模式需要三个参数 IvParameterSpec

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

6.应用场景:android缓存到本地的数据加密

可逆的,可以使用对称加密(或者非对称RSA)

DES和AES: 优先使用AES, 安全系数更高

7.非对称加密

Kotlin学习笔记——加密解密_第5张图片

为什么要互换公钥???这样双方才可以交流吧,

Kotlin学习笔记——加密解密_第6张图片

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) {
    //如何生成密钥对
    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字节

Kotlin学习笔记——加密解密_第7张图片

Kotlin学习笔记——加密解密_第8张图片

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.总结

Kotlin学习笔记——加密解密_第9张图片

13.消息摘要

Kotlin学习笔记——加密解密_第10张图片

消息摘要需要注意的:

Kotlin学习笔记——加密解密_第11张图片

消息摘要应用场景:一般不可逆的,都用消息摘要

Kotlin学习笔记——加密解密_第12张图片

下图中的登录接口,密码是明文登录,容易被抓包,不安全,一般会采用md5加密,为了增加破解难度,会多次加密,同时再结果后加盐(就是拼接自定义字符串)

Kotlin学习笔记——加密解密_第13张图片

14.数字签名

Kotlin学习笔记——加密解密_第14张图片


15.数字签名流程图

Kotlin学习笔记——加密解密_第15张图片


16.加密算法总结

Kotlin学习笔记——加密解密_第16张图片

Kotlin学习笔记——加密解密_第17张图片

Kotlin学习笔记——加密解密_第18张图片

Kotlin学习笔记——加密解密_第19张图片

Kotlin学习笔记——加密解密_第20张图片


你可能感兴趣的:(加密解密)