[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保護密碼的強度。