当前位置: 首页 > article >正文

Android上的AES加密

基础算法说明

https://www.youtube.com/watch?v=lnKPoWZnNNM

虽然这个视频讲的非常详细,但是涉及到具体底层算法,大致流程

1. 将数据转成HEX或者byte array

2.将数据分层一块块等大小的数据

3.将数据和key 进行一次混合,加密之后的输出,在生成新的key

4.将新的key和下一个数据,进行加密计算,继续重复

生成的KEY长度有128,192,256,不同的的长度对算法的速度有影响

当然key的长度越长,可能越安全这样

具体的算法是什么呢

为什么要有IV

另外这篇

https://www.youtube.com/watch?v=uWEPEBmFBHw

我们在AES的时候,有key了,为什么要IV呢

大概解释是,IV是个Ramdom的参数,不然每次用key算出来的值是一样的,

所以加上IV后,计算出来的结果会不一样。

Android上的具体AES实现

然后就是PL这个在Android上AES加密的具体实现

https://github.com/philipplackner/AndroidCrypto/tree/encrypt/decrypt

或者参考这个文档

https://medium.com/@jerry.cho.dev/android-keystore-aa7d2b43adfe

基本差不多

1.加密管理器

key的初始化和获取

@RequiresApi(Build.VERSION_CODES.M)
class CryptoManager {

    //获取keystroe,用于存放加密的key
    private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply {
        load(null)
    }

    //获取加密器,模式是ENCRYPT_MODE
    private val encryptCipher get() = Cipher.getInstance(TRANSFORMATION).apply {
        init(Cipher.ENCRYPT_MODE, getKey())
    }

    //解码器,模式DECRYPT_MODE,
    private fun getDecryptCipherForIv(iv: ByteArray): Cipher {
        return Cipher.getInstance(TRANSFORMATION).apply {
            init(Cipher.DECRYPT_MODE, getKey(), IvParameterSpec(iv))
        }
    }

    //加密秘钥,存储在keystroe中
    private fun getKey(): SecretKey {
        val existingKey = keyStore.getEntry("secret", null) as? KeyStore.SecretKeyEntry
        return existingKey?.secretKey ?: createKey()
    }

    private fun createKey(): SecretKey {
        return KeyGenerator.getInstance(ALGORITHM).apply {
            init(
                KeyGenParameterSpec.Builder(
                    "secret",
                    KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
                )
                    .setBlockModes(BLOCK_MODE)
                    .setEncryptionPaddings(PADDING)
                    .setUserAuthenticationRequired(false)
                    .setRandomizedEncryptionRequired(true)
                    .build()
            )
        }.generateKey()
    }

    //把byte进行加密,写入IV,写入机密后的bytes
    fun encrypt(bytes: ByteArray, outputStream: OutputStream): ByteArray {
        val encryptedBytes = encryptCipher.doFinal(bytes)
        outputStream.use {
            it.write(encryptCipher.iv.size)
            it.write(encryptCipher.iv)
            it.write(encryptedBytes.size)
            it.write(encryptedBytes)
        }
        return encryptedBytes
    }

    //解码,读取IV,根据IV再解码
    fun decrypt(inputStream: InputStream): ByteArray {
        return inputStream.use {
            val ivSize = it.read()
            val iv = ByteArray(ivSize)
            it.read(iv)

            val encryptedBytesSize = it.read()
            val encryptedBytes = ByteArray(encryptedBytesSize)
            it.read(encryptedBytes)

            getDecryptCipherForIv(iv).doFinal(encryptedBytes)
        }
    }

    companion object {
        private const val ALGORITHM = KeyProperties.KEY_ALGORITHM_AES
        private const val BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC
        private const val PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7
        private const val TRANSFORMATION = "$ALGORITHM/$BLOCK_MODE/$PADDING"
    }

}

        

2.加密

val bytes = messageToEncrypt.encodeToByteArray()
                            val file = File(filesDir, "secret.txt")
                            if(!file.exists()) {
                                file.createNewFile()
                            }
                            val fos = FileOutputStream(file)

                            messageToDecrypt = cryptoManager.encrypt(
                                bytes = bytes,
                                outputStream = fos
                            ).decodeToString()

3.解密

 val file = File(filesDir, "secret.txt")
                            messageToEncrypt = cryptoManager.decrypt(
                                inputStream = FileInputStream(file)
                            ).decodeToString()


http://www.kler.cn/news/357034.html

相关文章:

  • 数据结构 - 树,再探
  • Python 遍历(Python Traversal)
  • STM32应用开发——BH1750光照传感器详解
  • Lucas带你手撕机器学习——线性回归
  • 记录Visio导出图片的文字与latex中文字大小一致的问题,和visio导出适用于论文的高清图片问题
  • Java项目-基于Springboot的应急救援物资管理系统项目(源码+说明).zip
  • 虾​皮​一​面​-​2
  • 数学归纳法——第一数学归纳法、第二数学归纳法步骤和示例
  • SpringBoot中的RedisTemplate对象中的setIfAbsent()方法有什么作用?
  • Mapbox GL 加载GeoServer底图服务器的WMS source
  • 开源的存储引擎--cantian
  • js 字符串与数组的操作
  • python【装饰器】
  • python中_init_.py 到底有啥用?
  • nvm安装,node多版本管理
  • 多级缓存-案例导入说明
  • 自定义多级联动选择器指南(uni-app)
  • Spring Boot实现的电影评论系统开发
  • 开发工具(上)
  • 【数据结构与算法】第2课—数据结构之顺序表