[TOC]
## 1 DES弱加密算法风险检测 # 09001
安全性要求高的应用程序必须避免使用不安全的或者强度弱的加密算法,现代计算机的计算能力使得攻击者通过暴力破解可以攻破强度弱的算法。例如,数据加密标准算法DES(密钥默认是56位长度、算法半公开、迭代次数少)是极度不安全的,使用类似EFF(Electronic Frontier Foundaton) Deep Crack的计算机在一天内可以暴力破解由DES加密的消息。
风险等级:`低危`
问题示例:
使用DES若加密算法,风险代码样例:
```
...
SecretKeySpec key = new SecretKeySpec(rawKeyData, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
...
```
通过正则表达式"DES/(\w){3}/.+Padding"匹配字符串常量。
建议:
建议使用安全性更高的AES加密算法。
## 2 不安全的密钥长度风险检测 # 09002
在使用RSA加密时,密钥长度小于512bit,小于512bit的密钥很容易被破解,计算出密钥。
风险等级:`低危`
问题示例:
```
public static KeyPair getRSAKey() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(512);
KeyPair key = keyGen.generateKeyPair();
return key;
}
```
对应的smali代码如下:
```
Ljava/security/KeyPairGenerator;->getInstance(Ljava/lang/String;)Ljava/security/KeyPairGenerator;
Ljava/security/KeyPairGenerator;->initialize(I)V
```
通过匹配上述函数,并根据initialize函数的参数值判断。
建议:
使用RSA加密时,建议密钥长度大于1024bit。
## 3 AES-ECB弱加密风险检测 # 09003
AES的ECB加密模式容易遭到字典攻击,安全性不够。
风险等级:`低危`
问题示例:
第一步,检测以下函数:
* getInstance(String transformation)
* getInstance(String transformation, String provider)
* getInstance(String transformation, Provider provider)
第二步,检测上述函数第一个参数值出现以下情况的任意一种,即可认为该检测项不安全,标记为`低危`。
* "AES",Android提供的AES加密算法API默认使用ECB模式
* "DES",DES默认是56位加密密钥,已经不安全
* "AES/ECB/xxx"
* "DES/ECB/xxx"
* "DESede/ECB/xxx"
```
...
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
...
```
建议:
避免使用ECB模式,建议使用CBC。
## 4 IVParameterSpec不安全初始化向量检测 # 09004
使用IVParameterSpec函数,如果使用了固定的初始化向量,那么密码文本可预测性高得多,容易受到字典攻击等。
风险等级:`低危`
问题示例:
初始化向量时,使用了硬编码到程序的常量。
byte[] iv = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
IvParameterSpec ips = new IvParameterSpec(iv)
匹配`Ljavax/crypto/spec/IvParameterSpec;-><init>([B)V`函数
建议:
IVParameterSpec初始化时,不使用常量vector。
## 5 RSA中不使用Padding风险检测 # 09005
使用RSA公钥时通常会绑定一个padding,原因是为了防止一些依赖于no padding时对RSA算法的攻击。
风险等级:`低危`
问题示例:
```
...
Cipher rsa = null;
try {
rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");
} catch (java.security.NoSuchAlgorithmException e) {}
catch (javax.crypto.NoSuchPaddingException e) {}
SecretKeySpec key = new SecretKeySpec(rawKeyData, "RSA");
Cipher cipher = Cipher.getInstance("RSA/NONE/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key);
...
```
用正则表达式`RSA/(\w){3}/NoPadding`匹配字符串常量
建议:
建议使用Padding模式。
## 6 KeyStore弱密码风险检测 # 09006
keytool是一个Java数据证书的管理工具,Keytool将密钥(key,私钥和公钥配对)和证书(certificates)存在一个称为keystore的文件中,并通过密码保护keystore中的密钥。如果密码设置过于简单,例如:123456、android等,则会导致keystore文件的私钥泄露,从而导致一系列的信息泄露风险。
风险等级:`高危`
检测方法:
(方法一)基于keytool命令行检测:
keytool -list -keystore debug.keystore
然后输入不安全的弱密码,若正常输出,表明该keystore文件存在弱密码风险
(方法二)基于pyjks的第三方python解析库
安装`pip install pyjks`
```
def check_keystore_pwd(self, jks_file, pwd):
try:
jks.KeyStore.load(jks_file, pwd)
return True
except Exception as e:
return False
```
然后通过通过常见的弱密码组合进行payload测试。
建议:
提高keystore保护密码的强度。