在信息安全方面有一个不成文的共识,就是尽可能不要自己造轮子,而是用那些成熟的、经过千锤百炼的轮子。
每个喜好钻研的程序员都免不了冒出这种念头:如果我自己发明出一种不为人知的加密算法,会不会比公开的算法更安全,能避免被破解?比如「用新算法加密http,替代https」。
不会,起码在https这个问题上绝对不可能。
下面来详细解释一下直接加密http数据来替代https会有哪些问题:
第一,性能问题。这一条最容易理解,浏览器通过http收到加密数据后,需要用javascript来执行解密算法,而https是浏览器原生支持的,两者的性能差距可能高达一到两个数量级。就算所有的安全问题都解决了,也不推荐这么做;
第二就是兼容性问题了。https其实不是单一算法,而是一系列算法和加密协议的整合。
从早期的SSL3.0一直进化到今天的TLS1.2以及起草中的TLS1.3协议;
密钥交换阶段的RSA、DHE等非对称加密算法;
加密信息传输过程中的AES、3DES等对称加密算法;
验证数据完整性的HMAC-SHA1、HMAC-SHA256等哈希算法;
包括使用中的和被淘汰的,林林总总合计有几十种之多。
而且随着攻击方式的进化和安全性要求的不断提升,新的算法不停加入,旧的算法不停被淘汰。
由于不同客户端和服务器所支持的算法类型有新有旧,所以任何https连接建立之前都要进行协商,选择双方都能支持又足够安全的算法后再进行加密连接。
那么,在客户端和服务端也都要同时维护不断进化的加密算法并进行协商,保证版本兼容性。否则这种加密协议就永远不能推广,只能在少数私有项目中使用。
第三,也是最重要的,我们来看看这种加密的的安全性如何吧,有多少地方可能被攻破。
我们假设性能不是问题,兼容性也暂不考虑,只讨论安全性。
javascript这种直接暴露源码的语言,就算混淆过也没有什么秘密可言,甚至能直接在浏览器中debug、引入插件、加载外部脚本等。单这点就远不如浏览器这种独立应用程序了,至少对浏览器进行恶意修改和注入的行为理论上是能被杀毒软件拦截的。
那么把外壳的安全也放在一边,仅说加密算法行不行?
先排除掉纯对称加密的方式。因为密钥通过明文传输,无论是预置还是每次更换都难以避免被截获。
那就只好重新造一次SSL/TLS的轮子了,即先通过RSA加密传输对称密钥,再通过此密钥加密往来数据。
但这样依然不行。尽管RSA是非对称算法,能保证加解密过程的安全,但公钥本身的传输仍然是可以被截获并篡改的。正如针对https的中间人攻击一样,如果在握手阶段伪造了公钥,则能够轻易截获之后的所有通信。https防范中间人攻击的方式是CA证书,所有网站证书都通过CA证书体系一级一级信任下来,而根证书是内置于操作系统中的,需要相当高的权限才能操作(当然不能百分百防范,但已经是很高的安全措施了)。
但如果把整套证书安全机制放在js脚本里执行,那跟原来相比简直是天上地下的差距,毫无安全性可言了。
以上只做了一些简单分析,自己开发的http加密就已经溃不成军。而且结论还建立在代码本身没有缺陷、没有漏洞的情况下。js这种弱类型语言出bug的几率有多高就不用多提了吧?
这并不是说自己造的轮子都毫无价值,出于学习和研究目的而编写算法甚至实现一些框架都是有意义的。但对于正式应用而言,永远是那些公开的、被广泛应用的技术方案更加靠谱。
开发一种不为人知的加密算法就像隐居山林的武术大师,凭想象构建了一套天下无敌的神奇功夫,但不出山则已,一出山就直接被业余散打运动员撂翻在地。只有每天都进行对抗训练,经受各种实战考验,才有可能成为真正的武林高手。