一、AES加密模式ECB弱加密风险
漏洞描述:
AES默认的加密模式是ECB,在ECB模式下,由于每块数据的加密是独立的因此加密和解密都可以并行计算,相同的明文块会被加密成相同的密文块,这种模式不能提供严格的数据保密性。
漏洞原理:
Java的Cipher.getInstance("AES)使用SunJCE实现,默认的加密模式是AES/ECB/PKCS5Padding。 分组加密的工作模式有ECB、CBC、CTR、GCM等,其中ECB是最简单的加密模式。这种模式不能提供严格的数据保密性。在Java代码中,以下几种写法都是不安全的:
Cipher cipher = Cipher.getInstance("AES"); //AES默认情况下使用ECB加密
Cipher cipher = Cipher.getInstance("AES/ECB");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
不安全的加密模式会导致消息密文容易被第三方破解篡改,给数据安全带来巨大风险。
修复建议:
根据业务场景选择AES或者SM4(国密)对称密码算法,并且加密模式不为ECB模式。比如使用AES加密算法并采用GCM模式,GCM提供了对消息的加密和完整性校验,防止密文被篡改。
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
二、DES、3DES弱加密风险
漏洞描述:
应用使用DES算法或3DES加密算法进行对称加密。
漏洞原理:
DES的有效密钥只有56位比特、算法半公开、迭代次数少,目前计算机的算力可以在有效时间内进行破解。为了保证安全,防止暴力破解 ,不使用DES进行加密。
风险代码示例:
Cipher cipher = Cipher.getInstance("DES");
3DES相当于是对每个数据块应用三次DES加密算法。
修复建议:
在使用对称加密时不要使用DES和3DES加密算法,根据业务场景选择AES或者SM4(国密)对称密码算法,并且加密模式不为ECB模式。示例:
public static String Encrypt(String sSrc, String sKey) throws Exception {
byte[] raw = sKey.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// AES加密算法,且不是ECB加密模式
byte[] rand = new byte[16];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(rand);
IvParameterSpec iv = new IvParameterSpec(rand);//AES加密算法CBC模式需要一个向量iv
cipher.init(Cipher.ENCRYPT\_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(sSrc.getBytes());
return new Base64().encode(encrypted);
}
三、RSA加密场景NoPadding风险
漏洞描述:
RSA加密时选择NoPadding填充模式。
漏洞原理:
RSA加密场景下,需要对明文(plaintext)进行填充(Padding),如果RSA加密时选择NoPadding填充模式,当明文字节数较少时,破解密文所需的计算资源相对较小
示例风险代码如下:
Cipher rsa = null;
try {
rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");} //风险代码,未设置padding
catch (java.security.NoSuchAlgorithmException e) {}
catch (javax.crypto.NoSuchPaddingException e) {}
SecretKeySpec key = new SecretKeySpec(rawKeyData, "RSA");
Cipher cipher = Cipher.getInstance("RSA/NONE/NoPadding"); //风险代码,未设置padding
cipher.init(Cipher.DECRYPT\_MODE, key);
修复建议:
RSA加密场设置Padding,推荐选用OAEPPadding模式。
示例代码如下:
Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");
cipher.init(Cipher.DECRYPT\_MODE, privateKey);
cipher.doFinal(miwen);
四、RSA弱秘钥风险
漏洞描述:
应用使用RSA非对称加密时, RSA密钥的模(modulus)长度小于2048bit。
漏洞原理:
当RSA密钥的模(modulus)长度小于2048bit时,具备高性能的电脑容易针对模(modulus)进行因子分解并计算出密钥
示例风险代码如下:
public static KeyPair getRSAKey() throws NoSuchAlgorithmException
{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance( "RSA" );
keyGen.initialize( 512 ); // 风险代码,密钥长度不足
KeyPair key = keyGen.generateKeyPair();
return(key);
}
修复建议:
使用RSA加密时,密钥长度不低于2048位。
示例代码如下:
public static KeyPair getRSAKey() throws NoSuchAlgorithmException
{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance( "RSA" );
keyGen.initialize( 2048 ); // 正确代码,密钥长度达到安全级别
KeyPair key = keyGen.generateKeyPair();
return(key);
}