【Kotlin】加密解密2:DES、AES加密和解密


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Api文档

https://docs.oracle.com/javase/7/docs/api/

DES加密解密

//单例
object DESCrypt{
    //des加密
    fun encrypt(input:String,password:String): ByteArray {
        //1.创建cipher
        val c = Cipher.getInstance("DES")
        //2.初始化cipher(参数1:加密/解密模式)
        val kf = SecretKeyFactory.getInstance("DES")
        val keySpec = DESKeySpec(password.toByteArray())

        val key: Key? = kf.generateSecret(keySpec)
        c.init(Cipher.ENCRYPT_MODE, key)
        //3.加密/解密
        val encrypt = c.doFinal(input.toByteArray())
        return encrypt
    }
    //des解密
    fun decrypt(input:ByteArray,password:String): ByteArray {
        //1.创建cipher
        val c = Cipher.getInstance("DES")
        //2.初始化cipher(参数1:加密/解密模式)
        val kf = SecretKeyFactory.getInstance("DES")
        val keySpec = DESKeySpec(password.toByteArray())

        val key: Key? = kf.generateSecret(keySpec)
        c.init(Cipher.DECRYPT_MODE, key)
        //3.加密/解密
        val encrypt = c.doFinal(input)
        return encrypt
    }
}

fun main(args: Array<String>) {
    //原文
    val input = "欢迎来到Errol_King的博客"
    //密码,密钥长度8位
    val password = "12345678"

    val encrypt = DESCrypt.encrypt(input,password)
    val decrypt = DESCrypt.decrypt(encrypt,password)
    println(String(decrypt))
}

在这里插入图片描述

Base64加密和解密

上面的栗子中用DES成功进行了加密和解密

之前加密返回的是bytearray,现在返回字符串,现在加密解密变成了

//单例
object DESCrypt{
    //des加密
    fun encrypt(input:String,password:String): String {
        //1.创建cipher
        val c = Cipher.getInstance("DES")
        //2.初始化cipher(参数1:加密/解密模式)
        val kf = SecretKeyFactory.getInstance("DES")
        val keySpec = DESKeySpec(password.toByteArray())

        val key: Key? = kf.generateSecret(keySpec)
        c.init(Cipher.ENCRYPT_MODE, key)
        //3.加密/解密
        val encrypt = c.doFinal(input.toByteArray())
        return String(encrypt)
    }
    //des解密
    fun decrypt(input:String,password:String): ByteArray {
        //1.创建cipher
        val c = Cipher.getInstance("DES")
        //2.初始化cipher(参数1:加密/解密模式)
        val kf = SecretKeyFactory.getInstance("DES")
        val keySpec = DESKeySpec(password.toByteArray())

        val key: Key? = kf.generateSecret(keySpec)
        c.init(Cipher.DECRYPT_MODE, key)
        //3.加密/解密
        val encrypt = c.doFinal(input.toByteArray())
        return encrypt
    }
}

fun main(args: Array<String>) {
    //原文
    val input = "欢迎来到Errol_King的博客"
    //密码,密钥长度8位
    val password = "12345678"
    
    val encrypt = DESCrypt.encrypt(input,password)
    println(encrypt)
    val decrypt = DESCrypt.decrypt(encrypt,password)
    println(String(decrypt))
}

运行程序
在这里插入图片描述
加密后变成了乱码,解密报错了

我们把原文改为“欢迎”

	//原文
    val input = "欢迎"
    val array = input.toByteArray()//转成字节数组
    array.forEach {
        println(it)
    }

utf8中,一个中文字符占3个字节
在这里插入图片描述
加密后为什么变成乱码了呢。打印一下加密后字节数组长度

fun encrypt(input:String,password:String): String {
        ......
        //3.加密/解密
        val encrypt = c.doFinal(input.toByteArray())
        //加密后字节数组的长度
        println("加密后字节数组长度"+encrypt.size)//8
        return String(encrypt)
    }

加密后变成了8个字符,在码表中找不到对应字符

在开发中用base64做编码节码,来解决乱码的问题

引入Base64的工具类

//单例
object DESCrypt{
    //des加密
    fun encrypt(input:String,password:String): String {
        ......
        return  Base64.encode(encrypt)
    }
    //des解密
    fun decrypt(input:String,password:String): ByteArray {
        ......
        //3.加密/解密
        val encrypt = c.doFinal(Base64.decode(input))
        return encrypt
    }
}

fun main(args: Array<String>) {
    //原文
    val input = "欢迎来到Errol_King的博客"
    //密码,密钥长度8位
    val password = "12345678"

    val encrypt = DESCrypt.encrypt(input,password)
    println(encrypt)
    val decrypt = DESCrypt.decrypt(encrypt,password)
    println(String(decrypt))
}

在这里插入图片描述
Base64工具类:
链接:https://pan.baidu.com/s/1FzMDzF5jRwu6U8aFNytrTg
提取码:kvs4

AES加密解密

object AESCrypt{
    //加密
    fun encrypt(input:String,password:String): String {
        //创建cipher对象
        val cipher = Cipher.getInstance("AES")
        //初始化:加密/解密
        val keySpec:SecretKeySpec = SecretKeySpec(password.toByteArray(),"AES")
        cipher.init(Cipher.ENCRYPT_MODE,keySpec)
        //加密
        val encrypt = cipher.doFinal(input.toByteArray())
        return Base64.encode(encrypt)
    }
    //解密
    fun decrypt(input:String,password:String): String {
        //创建cipher对象
        val cipher = Cipher.getInstance("AES")
        //初始化:加密/解密
        val keySpec:SecretKeySpec = SecretKeySpec(password.toByteArray(),"AES")
        cipher.init(Cipher.DECRYPT_MODE,keySpec)
        //因为传过来的是Base64加密后的字符串,所以先Base64解密
        val encrypt = cipher.doFinal(Base64.decode(input))
        return String(encrypt)
    }
}

fun main(args: Array<String>) {
    //AES密码必须是16位
    val password = "1234567812345678"
    val input = "欢迎"

    val e = AESCrypt.encrypt(input,password)
    val d = AESCrypt.decrypt(e,password)
    println(e)
    println(d)
}

在这里插入图片描述

DES和AES密钥长度

在这里插入图片描述
DES后都带有56

val password8 = "12345678"
println(password8.toByteArray().size)//8个字节,8*8=64位,DES前7位参与计算,最后一位作为校验码,7*8=56

AES后都带有128

    val password16 = "1234567812345678"
    println("AES密钥字节长度:"+password16.toByteArray().size)//16个字节,16*8=128

工作模式和填充模式

在这里插入图片描述
看之前的api文档,AES/DES是加密算法,中间的是工作模式,最后的是填充模式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先使用ECB的工作模式

object DESCrypt{
    //算法/工作模式/填充模式
    val transformation = "DES/ECB/PKCS5Padding"
    //算法
    val algorithm = "DES"

    //des加密
    fun encrypt(input:String,password:String): String {
        //1.创建cipher
        val c = Cipher.getInstance(transformation)
        //2.初始化cipher(参数1:加密/解密模式)
        val kf = SecretKeyFactory.getInstance(algorithm)
        val keySpec = DESKeySpec(password.toByteArray())

        val key: Key? = kf.generateSecret(keySpec)
        c.init(Cipher.ENCRYPT_MODE, key)
        //3.加密/解密
        val encrypt = c.doFinal(input.toByteArray())
        return  Base64.encode(encrypt)
    }
    //des解密
    fun decrypt(input:String,password:String): ByteArray {
        //1.创建cipher
        val c = Cipher.getInstance(transformation)
        //2.初始化cipher(参数1:加密/解密模式)
        val kf = SecretKeyFactory.getInstance(algorithm)
        val keySpec = DESKeySpec(password.toByteArray())

        val key: Key? = kf.generateSecret(keySpec)
        c.init(Cipher.DECRYPT_MODE, key)
        //3.加密/解密
        val encrypt = c.doFinal(Base64.decode(input))
        return encrypt
    }
}

fun main(args: Array<String>) {
    //原文
    val input = "欢迎来到Errol_King的博客"
    //密码,密钥长度8位
    val password = "12345678"

   val encrypt = DESCrypt.encrypt(input,password)
    println(encrypt)
    val decrypt = DESCrypt.decrypt(encrypt,password)
    println(String(decrypt))
}

在这里插入图片描述
再来使用CBC的工作模式

object DESCrypt{
    //算法/工作模式/填充模式
    val transformation = "DES/CBC/PKCS5Padding"
    //算法
    val algorithm = "DES"

    //des加密
    fun encrypt(input:String,password:String): String {
        //1.创建cipher
        val c = Cipher.getInstance(transformation)
        //2.初始化cipher(参数1:加密/解密模式)
        val kf = SecretKeyFactory.getInstance(algorithm)
        val keySpec = DESKeySpec(password.toByteArray())

        val key: Key? = kf.generateSecret(keySpec)
        val iv = IvParameterSpec(password.toByteArray())
        c.init(Cipher.ENCRYPT_MODE, key,iv)//CBC需要额外参数
        //3.加密/解密
        val encrypt = c.doFinal(input.toByteArray())
        return  Base64.encode(encrypt)
    }
    //des解密
    fun decrypt(input:String,password:String): ByteArray {
        //1.创建cipher
        val c = Cipher.getInstance(transformation)
        //2.初始化cipher(参数1:加密/解密模式)
        val kf = SecretKeyFactory.getInstance(algorithm)
        val keySpec = DESKeySpec(password.toByteArray())

        val key: Key? = kf.generateSecret(keySpec)
        val iv = IvParameterSpec(password.toByteArray())
        c.init(Cipher.DECRYPT_MODE, key,iv)//CBC需要额外参数
        //3.加密/解密
        val encrypt = c.doFinal(Base64.decode(input))
        return encrypt
    }
}

fun main(args: Array<String>) {
    //原文
    val input = "欢迎来到Errol_King的博客"
    //密码,密钥长度8位
    val password = "12345678"

   val encrypt = DESCrypt.encrypt(input,password)
    println(encrypt)
    val decrypt = DESCrypt.decrypt(encrypt,password)
    println(String(decrypt))
}

运行结果相同

对称加密的应用场景

手机连接AS,data-data-com.tencent.mobileqq-databases中找到qq号.db,下载到电脑,用SQLite打开,如果关联了手机联系人,phoneContact中会有数据。但是加密的,这里用到的就是对称加密

发布了640 篇原创文章 · 获赞 143 · 访问量 54万+

猜你喜欢

转载自blog.csdn.net/u010356768/article/details/103701092