文章目录


【Kotlin】加密解密2:DES、AES加密和解密_初始化

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

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

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))
}

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

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))
}

运行程序
【Kotlin】加密解密2:DES、AES加密和解密_AES_05
加密后变成了乱码,解密报错了

我们把原文改为“欢迎”

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

utf8中,一个中文字符占3个字节
【Kotlin】加密解密2:DES、AES加密和解密_工作模式_06
加密后为什么变成乱码了呢。打印一下加密后字节数组长度

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))
}

【Kotlin】加密解密2:DES、AES加密和解密_初始化_07
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)
}

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

DES和AES密钥长度

【Kotlin】加密解密2:DES、AES加密和解密_Base64_09
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

工作模式和填充模式

【Kotlin】加密解密2:DES、AES加密和解密_工作模式_10
看之前的api文档,AES/DES是加密算法,中间的是工作模式,最后的是填充模式
【Kotlin】加密解密2:DES、AES加密和解密_初始化_11
【Kotlin】加密解密2:DES、AES加密和解密_Base64_12
【Kotlin】加密解密2:DES、AES加密和解密_DES_13
先使用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))
}

【Kotlin】加密解密2:DES、AES加密和解密_DES_14
再来使用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中会有数据。但是加密的,这里用到的就是对称加密