【代码扫描修复】弱HASH(中危)
漏洞描述:
摘要: MD2、MD4、MD5、RIPEMD-160 和 SHA-1 是常用的加密散列算法,通常用于验证消息和其他数据的完整性。然而,由于最近的密码分析研究揭示了这些算法中存在的根本缺陷,因此它们不应该再用于安全性关键的上下文中。 由于有效破解 MD 和 RIPEMD 散列的技术已得到广泛使用,因此不应该依赖这些算法来保证安全性。对于 SHA-1,目前的破坏技术仍需要极高的计算能力,因此比较难以实现。然而,攻击者已发现了该算法的致命弱点,破坏它的技术可能会导致更快地发起攻击。 缺陷描述: 弱加密散列值无法保证数据完整性,且不能在安全性关键的上下文中使用。
解决方案:
官方建议:
停止使用 MD2、MD4、MD5、RIPEMD-160 和 SHA-1 对安全性关键的上下文中的数据进行验证。 目前,SHA-224、SHA-256、SHA-384、SHA-512 和 SHA-3 都是不错的备选方案。 但是,由于安全散列算法 (Secure Hash Algorithm) 的这些变体并没有像 SHA-1 那样得到仔细研究,因此请留意可能影响这些算法安全性的未来研究结果。
对于没有上线的系统我们可能还可以采用官方的建议,如果是已经上线并产生了大量数据的系统,针对这种漏洞,我们只能通过更复杂的调用绕过了。。。
临时修复方案:
这里我项目中主要是使用了 Apache 的 commons-codec 编码解码工具包,来实现 md5 加密和 SHA-1 加密。
我们临时处理的方式非常简单,就是通过使用 Hutool 的工具类来替换掉 commons-codec 工具包。
md5加密:
修复前:
import org.apache.commons.codec.digest.DigestUtils; byte[] md5Bytes = DigestUtils.md5("test".getBytes()); String md5Hex = DigestUtils.md5Hex("test".getBytes());
修复后:
import cn.hutool.crypto.digest.DigestAlgorithm; import cn.hutool.crypto.digest.Digester; byte[] md5Bytes = new Digester(DigestAlgorithm.MD5).digest(pwd); String md5Hex = new Digester(DigestAlgorithm.MD5).digestHex("test");
SHA-1加密:
修复前:
import org.apache.commons.codec.digest.DigestUtils; byte[] sha1Bytes = DigestUtils.sha1(System.currentTimeMillis() + ""); String sha1Hex = DigestUtils.sha1Hex(System.currentTimeMillis() + "");
修复后:
import cn.hutool.crypto.digest.DigestAlgorithm; import cn.hutool.crypto.digest.Digester; byte[] sha1Bytes = new Digester(DigestAlgorithm.SHA1).digest(System.currentTimeMillis() + ""); String sha1Hex = new Digester(DigestAlgorithm.SHA1).digestHex(System.currentTimeMillis() + "");
关于 SHA-1 摘要算法我们可以验证一下,并打印下其它 SHA 加密方式看看:
public static void main(String[] args) { long l = System.currentTimeMillis(); String sha1Hex = DigestUtils.sha1Hex(l + ""); String sha1Hex2 = new Digester(DigestAlgorithm.SHA1).digestHex(l + ""); System.out.println(Objects.equals(sha1Hex, sha1Hex2)); System.out.println("SHA1: " + new Digester(DigestAlgorithm.SHA1).digestHex(l + "")); System.out.println("SHA256: " + new Digester(DigestAlgorithm.SHA256).digestHex(l + "")); System.out.println("SHA384: " + new Digester(DigestAlgorithm.SHA384).digestHex(l + "")); System.out.println("SHA512: " + new Digester(DigestAlgorithm.SHA512).digestHex(l + "")); }
执行结果:
true SHA1: a178401f0dc8c03177978bfc5a9e7de7d3b41fdd SHA256: 8c69e4b1ec8034b4c58c23633986f65ff8d8e159f1775560bf50881ba6030ea7 SHA384: 226d77d64f029eaeb5b5c20e57c5270f0ceedd14e468207e6a30cddc32f96f954e5a225eacf43aca345be1d8629e37b1 SHA512: d0f67ffe5abebf1955762871dc3991e4cddb620b803e32969d09a41457a0c1f273532bbb0a89b94b965ac1dbebb3800ef0f47fd8b40a4d56ddfe8dfb0d684696
我们可以看到替换后的摘要串和之前是一致的,不同SHA加密算法加密后的长度会不一样,而且数字越大加密后的内容越长。
整理完毕,完结撒花~ 🌻