历史上的苏格兰女王玛丽(又名玛丽·斯图亚特)是最具悲剧性的女王之一。除去她充满戏剧性又跌宕起伏的一生,这里要说一下造成她悲剧的一件小事。

在16世纪,当时的苏格兰女王玛丽曾认为没有人能破译自己使用的密码。正是由于对密码的盲信,她将刺杀伊丽莎白女王的计划明明白白写在密信中,结果密码遭到破译,玛丽也因此被送上断头台。

提到《玛丽·斯图亚特的刺杀密信》这个小故事是出于在开发安全加解密动态库时对于密码,算法和信息安全的一些思考和感想:

开发安全加解密动态库的初衷是为了隐藏数据的加密解密逻辑使得加密的数据更为安全,同时为联机加解密功能提供本地降级方案。由于要在应用本地实现数据的加密和解密,所以动态库也提供了应用本地和服务端的密钥安全交换功能。围绕密钥安全,算法逻辑和密钥交换我们做了很多思考,也绕过了一些思维误区。

就算密码的强度再低,也比完全不加密要强

其实这样的想法是非常危险的。

正确的想法应该是:与其使用低强度的密码,还不如从一开始就不使用任何密码。

这主要是由于用户容易通过“密码”这一词获得一种“错误的安全感”。对于用户来说,安全感与密码的强度无关。而只是由“信息已经被加密了”这一事实产生的,而通常会导致用户在处理一些机密信息的时候麻痹大意。就像文章开头提到的《玛丽·斯图亚特的刺杀密信》事件。

密码强度,是指一个密码对抗猜测或是暴力破解的有效程度。

一般来说,指一个未授权的访问者得到正确密码的平均尝试次数。密码的强度和其长度、复杂度及不可预测度有关。强密码可以降低安全漏洞的整体风险,但并不能降低采取其他安全措施的需要。

攻击者可以提交猜测到的密码的速率是衡量一个系统安全性的重要因素。有的系统在多次尝试失败后会暂停登入一段时间,在没有其他安全缺陷时,这种系统可以用相对简单的密码保护。但是系统必须以某种形式存储用户密码,而当这些数据被盗时,就有极大的危险。

固定长度的密码天然存在被暴力遍历的风险,所以我们推荐使用变长的密钥。

像MD5这种容易被彩虹表碰撞破解的离散摘要方式,属于低密码强度的离散摘要算法,建议在使用SHA1或SM3等更安全的离散摘要算法来保护密码。

所以在做本地动态库安全加解密的过程中,设计开始就需要杜绝弱密码的可能,在程序的底层就强化密码的强度校验和使用更高级的离散摘要算法来保护本地授权密码。

保密算法比开源算法要安全

很多公司都有这样的想法:“由公司自己开发的一种密码算法,并将这种算法保密,这样就能保证安全。”

然而,这样想法却是大错特错,使用保密的密码算法是无法获得高安全性的。不应该制作或使用任何保密的密码算法,而是应该使用那些已经公开的、被公认为强度较高的密码算法。

这样做主要是两个原因:

  • 加密算法早晚会公诸于世

从历史上看,加密算法最终无一例外地会被暴露出来。例如RSA公司开发的RC4密码算法曾经也是保密的,但最终还是被一位匿名人士开发并公开了与其等效的程序。一旦密码算法的详细信息被暴露,依靠对密码算法本身进行保密来确保机密性的密码系统也就土崩瓦解了。反之,那些公开的算法从一开始就没想过要保密,因此算法的暴露丝毫不会削弱它们的强度。

  • 开发高强度的密码算法是非常困难的

要比较密码算法的强弱是极其困难的,因为密码算法的强度并不像数学那样可以进行严密的证明。密码算法的强度值能通过事实来证明,如果专业密码破译者经过数年的尝试仍然没有破解某个密码算法,则说明这种算法的强度较高。

稍微聪明一点的程序员很容易就能够编写出“自己的密码系统”。这样的密码在外行看来貌似牢不可破,但在专业密码破译者眼里,要破解这样的密码几乎是手到擒来。

现在世界上公开的被认为强度较高的密码算法,几乎是经过密码破译者长期尝试破解未果而存活下来的。因此,如果认为“公司自己开发的密码系统比那些公开的密码系统更强”,那只能说是过于高估自己公司的能力了。

试图通过对密码算法本身进行保密来确保安全性的行为,一般称为隐藏安全性,这种行为是危险且愚蠢的。

反过来说,将密码算法的详细信息以及程序源代码全部交给专业密码破译者,并且为其提供大量的明文和密文样本,如果在这样的情况下破译一段新的密文依然需要花上相对长的时间,就说明这是高强度的密码。

既然开发高强度的加密算法是如此困难是否可以考虑对开源算法魔改的可行性呢?

标准AES算法的加密和解密流程如下:

对于已经成熟的安全算法,例如:AES算法,做一定程度的算法魔改还是可行的。

例如:算法魔改可以集中在以下几点:

  • S盒变换算法魔改

  • 密钥的轮变换魔改

  • 密钥的扩展魔改

虽然动态库开发过程中,也是用了大量的开源算法,但是我们还是魔改了一些开源算法来满足终端设备加密和解密的独占性要求,防止密钥泄漏后被标准算法轻易破解密文。

非对称加密强于对称加密

对称密码的密钥安全极其重要,加密者和解密者需要提前协商密钥,并各自确保密钥的安全性,一但密钥泄露,即使算法是安全的也无法保障原文信息的私密性。

很多人就认为:“在实际的使用中,远程的提前协商密钥不容易实现,即使协商好,在远程传输过程中也容易被他人获取,因此非对称密钥强于对称加密”。

其实这种想法是错误的,两种加密方式的优缺点如下:

对称加密和非对称加密,各有各的优点,也各有缺点。而将他们组合到一起,的确是一种不错的选择。取对称密码之长补公私钥密码之不足,取公钥密码之长补对称密码之不足,下面我们将开启混合加密之旅。

所谓混合加密其实就是使用非对称加密保护密钥的传递过程,标准的SSL密钥交换协议就是使用了这种混合加密模式。

混合密码系统中会先用对称密码来对消息进行加密,这样消息就被转换为密文,从而保证消息的机密性,然后我们只要保证对称密码的机密性就可以啦。用公有密码对加密消息时使用的对称密码的密钥进行加密。由于密钥比较短,公钥密码速度慢的问题就得以解决啦。

混合密码系统组成机制:

  • 用对称密码加密消息

  • 用伪随机数生成器生成对称密码加密中使用的会话密钥

  • 用公钥密码加密会话密钥

  • 从混合密码系统外部赋予公钥密码加密中使用的会话密钥

由于动态库是在本地执行的,所以我们自然就遇到了密钥分发的问题。

在初始化动态库的时候,我们就使用了混合密钥系统。对称密钥用于动态库实现数据的加密和解密,使用非对称密钥来完成会话密钥的加密保护。

目前安全动态库已经在生产系统中正式使用,作为实时加解密服务的本地降级方案。同时ndk编译后的动态库也可以为移动设备,例如android手机等终端设备提供安全保护。密码,算法和信息安全,整合在一个小小的动态库中,我们的目标是从密码出发保障信息安全,避免《玛丽·斯图亚特的刺杀密信》事件的复发。

开发过程中踩了不少的“坑”,我们还是得出了不少的经验的,我要开始念经了(笑^_^!):

1、由于动态库是分发在终端设备使用的,所以一旦动态库开始下发使用,想要升级或回收动态库将会是一个很困难的过程,所以在设计动态库最初就要按最小化功能设计动态库,确保动态库每个功能的独立性,任何扩展性的功能都需要在外部封装的SDK中实现。

2、动态库对外提供api可以使用jni和jna两种方式,在使用的过程中jna会更加方便,而且友好,但是在兼容性上jna方式并没有jni更为实用,特别是android设备等使用jni调用会更加方便。

3、动态库在开发过程中需要注意内存泄漏的问题,由于动态库会长驻系统内存运行,所以要尽量管控内存的使用,防止一个小失误把应用服务的内存耗尽。

4、做好动态库多版本的兼容管理,毕竟你不知道客户端是否在使用低级版本的程序。

5、做一些动态库的防破解处理,例如简单的做一下加壳,编译时做代码混淆。

6、为设备颁发授权密钥用于动态库激活使用,防止动态库被未授权使用。

目前动态库的设计还只是动态库在终端的安全设计,只是一个基础组件,下一版本我们准备整合终端管理(TMS),这样可以进一步管理动态库,并能够实现动态库在终端上的自动更新升级,好处有以下几点:

  • 扩大安全管控的自主权,可以为 设备定制化分发动态库

  • 增加动态库多版本管理,实现多设备的灰度发布

  • 整合业务系统,实现动态库功能的业务零侵入

作者简介

江小鱼,中通快递高级信息安全工程师,主要负责中通快递信息安全推送和加解密基础设施搭建,负责维护中通实名制服务,参与信息安全审计和安全加固工作。

相关参考:

密码破解之彩虹表

http://www.ha97.com/4009.html

twofish魔改算法的逆向

http://blog.iyzyi.com/index.php/archives/1618/

MD5:一个已经过时的算法

http://bobao.360.cn/learning/detail/564.html

8种方法 加强您的密码强度

https://www.sohu.com/a/247328797_765820

简单了解AES加密标准

https://www.jiamisoft.com/blog/23338-aesjmbz.html

密码学和对称密钥算法

https://zhuanlan.zhihu.com/p/150102273

SSL/TLS 双向认证(一) -- SSL/TLS 工作原理

https://blog.csdn.net/ustccw/article/details/76691248

声明:本文来自中通安全应急响应中心,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。