基础算法说明
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()