title: Android 常用加密算法
date: 2020-03-02
tag: Android
category: Android
Android 常用加密算法
数字签名:
简单来说就是提供可鉴别的数字信息验证自身身份的一种方式。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。分别又发送者持有能够代表自己身份的私钥(不可泄漏),由接受者持有与私钥对应的公钥,能够在接受到来自发送者信息时用于验证身份。
对称加密
加密和解密密钥相同,加解密过程可逆
-
DES
Data Encryption Standard,数据加密算法
Key:8字节
Data:8字节,数据
Mode:DES工作模式,有ECB(电子密码本模式)、CBC(加密分组链接模式 )、CFB(加密反馈模式)、OFB(输出反馈模式)、CTR(计数器模式);NoPadding(不填充)、Zeros填充(0填充)、PKCS5Padding填充
示例:
@SuppressLint("GetInstance") fun desEncrypt(content: ByteArray, pwd: ByteArray): ByteArray { val random = SecureRandom() val desKey = DESKeySpec(pwd) val keyFactory = SecretKeyFactory.getInstance("DES") val secureKey = keyFactory.generateSecret(desKey) val cipher = Cipher.getInstance("DES") cipher.init(Cipher.ENCRYPT_MODE, secureKey, random) return cipher.doFinal(content) } @SuppressLint("GetInstance") fun desDecrypt(content: ByteArray, pwd: ByteArray): ByteArray { val random = SecureRandom() val desKey = DESKeySpec(pwd) val keyFactory = SecretKeyFactory.getInstance("DES") val secureKey = keyFactory.generateSecret(desKey) val cipher = Cipher.getInstance("DES") cipher.init(Cipher.DECRYPT_MODE, secureKey, random) return cipher.doFinal(content) }
-
3DES
Triple DES,三重数据加密算法,相当于是对每个数据块应用三次数据加密标准(DES)算法,加长了密钥长度
fun tripleDesEncrypt(data: ByteArray, key: ByteArray): ByteArray { val desKey = DESedeKeySpec(key) val keyFactory = SecretKeyFactory.getInstance("desede") val secureKey = keyFactory.generateSecret(desKey) val cipher = Cipher.getInstance("desede/ECB/PKCS5Padding") cipher.init(Cipher.ENCRYPT_MODE, secureKey) return cipher.doFinal(data) } fun tripleDesDecrypt(data: ByteArray, key: ByteArray): ByteArray { val desKey = DESedeKeySpec(key) val keyFactory = SecretKeyFactory.getInstance("desede") val secureKey = keyFactory.generateSecret(desKey) val cipher = Cipher.getInstance("desede/ECB/PKCS5Padding") cipher.init(Cipher.DECRYPT_MODE, secureKey) return cipher.doFinal(data) }
-
AES
Advanced Encryption Standard,高级加密标准,取代DES而出现
private const val AES_ITERATION_COUNT = 1000 private const val AES_SALT_LEN = 32 // bytes 128 / 8 --> AES 128 private const val IV = "0000000000000000" private var salt: ByteArray //此处的盐值需要自己保存,或者自己保存密钥 init { val random = SecureRandom() salt = ByteArray(AES_SALT_LEN) random.nextBytes(salt) } private fun getRawKey(key: CharArray): ByteArray { val keySpec = PBEKeySpec(key, salt, AES_ITERATION_COUNT, AES_SALT_LEN * 8) val keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1") return keyFactory.generateSecret(keySpec).encoded } fun aesEncrypt(data: ByteArray, key: CharArray, iv: ByteArray): ByteArray { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") val keys = getRawKey(key) cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(keys, "AES"), IvParameterSpec(iv)) return cipher.doFinal(data) } fun aesDecrypt(data: ByteArray, key: CharArray, iv: ByteArray): ByteArray { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") val keys = getRawKey(key) cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(keys, "AES"), IvParameterSpec(iv)) return cipher.doFinal(data) }
由于AES在Android N开始,移除了
"SHA1PRNG"
算法和"Crypto"
provider,不能通过这两者来获取随机数进而获取密钥,所以在N后的系统运行都会出错,官方推荐使用以上的方式 Security “Crypto” provider deprecated in Android N ,获取密钥。也可以采用一些第三方的库或者自己实现
CryptoProvider
类——>参考Android AES加解密(兼容Android7.0),或者直接用密码作为key(这种方式需要保证password为16位)fun aesEncrypt(data: ByteArray, key: ByteArray, iv: ByteArray): ByteArray { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(key, "AES"), IvParameterSpec(iv)) return cipher.doFinal(data) } fun aesDecrypt(data: ByteArray, key: ByteArray, iv: ByteArray): ByteArray { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(key, "AES"), IvParameterSpec(iv)) return cipher.doFinal(data) }
非对称加密
加密和解密密钥不同
-
RSA
目前最有影响力的公钥加密算法,能抵抗目前已知所有密码攻击
公钥私钥对
-
DSA
Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。它是一种公开密钥算法,用作数字签名。DSA加密算法使用公开密钥,为接受者验证数据的完整性和数据发送者的身份,它也可用于由第三方去确定签名和所签数据的真实性
-
ECC
它比其他的方法使用 更小的密钥,比如
RSA
加密算法,提供 相当的或更高等级 的安全级别。不过一个缺点是 加密和解密操作 的实现比其他机制 时间长 (相比RSA
算法,该算法对CPU
消耗严重)
其他散列算法
摘要算法,不可逆过程,经过算法运算后都是生成固定长度的数据,使用16进行进行显示
-
SHA-1
160位摘要,强度更高
val shaDigest = MessageDigest.getInstance("SHA-1") shaDigest.update(bytes) return shaDigest.digest()
-
MD5
1228位摘要,速度更快
val shaDigest = MessageDigest.getInstance("MD5") shaDigest.update(bytes) return shaDigest.digest()
其他摘要算法类似
对比
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EaVUN3bI-1586740512222)(https://raw.githubusercontent.com/MinorPeng/Image/master/android_encryption_compare.png)]