在我们一般的系统交互中,对数据加密传输的场景必不可少,如果我们简单的把秘钥硬编码在代码中、放在配置文件中或者统一配置中心中,都不安全,很容易导致秘钥的泄露;那么有没有一个像保险柜一样的安全设备来帮我们出秘钥,并且提供明文加密和密文解密的功能呢?KenCenter应用而生。
KeyCenter中的运行方式:
设计的领域模型:应用、秘钥、服务;
(1)创建应用;用于空间隔离。
(2)在应用下创建秘钥;算法支持对称加密(加密解密)、非对称加密(签名验签或RSA的加解密)、哈希类型(签名验签),我们在创建秘钥的时候,需要给这个秘钥起一个应用下唯一的别名,这个别名用于与秘钥进行关联,别名泄露并不会给系统带来风险;
(3)我们可以使用KeyCenter提供的服务接口,对明文进行加密,或者对密文进行解密。
对称加密实例:
1 | String ciphertext/**密文**/ = cryptograph.encrypt("待加密的明文", "密钥别名"); |
加解密的过程就想到于我们把信息送到了一个不为外认知的情报局,这个情报局根据我指定的秘钥别名,进行数据加解密操作,具体的操作对外部完全是黑盒,没有外人能进入到者情报局,情报局里面的机密数据也是不允许从情报局中携带出来。
疑问:
(1)我设置的秘钥,在KeyCenter中是如何存储的?
如果是明文存储,那么能看到KeyCenter数据库的人就能获取到我们的秘钥信息了,KeyCenter的解决方案是先对密钥进行多重加密,然后存在数据库里;我们即使能看到数据库里的内容,看到的也只是加密后的秘钥,然后问题来了,在对密钥进行加密时,又需要另外的密钥。即使是多重加密,最终肯定还会存在一个根密钥(root key)。
(2)根密钥怎么安全存放呢?有人拿到根密钥,不就可以将所有密钥解密出来吗?
解决方案:加密机(或称为密码机),提供硬件级别的密钥管理和加密计算。
KeyCenter部署方式:
目前面向业务系统的KeyCenter应用,采用的是中心化部署方式,没有进行单元化部署,原因是不希望密钥大规模同步到另外一个机房,增加安全风险,另外,keycenter之上还有一层物理加密机,这个只能中心部署。
中心化部署的KeyCenter具有单点风险,其他单元访问KeyCenter这是跨单元访问,如果KeyCenter挂了怎么办?目前采用的容灾策略是,牺牲掉一定的安全性,把密钥缓存在业务系统内存中,只要业务系统不重启,密钥就不会丢失;这也给KeyCenter赢得了一定的故障恢复时间。
利用SSL-KeyCenter存储https的私钥
信息明文在网络中裸奔的年代在组件过去,越来越多的企业接入HTTPS,让数据传输变得更安全。在HTTPS进行SSL的过程中,我们首先会使用非对称加密来传输客户端中的random随机数用于生成会话秘钥的一部分,服务端会保存私钥信息,如果私钥信息泄露,会给通信安全带来很大的威胁,所以很有必要保障私钥的安全;其次,如果一个集团中存在很多应用上了HTTPS,那么可信证书的私钥也就需要一个系统来进行统一管理,使用KeyCenter再合适不过了,但是在阿里内部,存储证书私钥的系统叫做SSL-KeyCenter,与解决业务密钥的KeyCenter是两个系统,我们很容易弄混淆。
测试发现,HTTPS的握手性能,很大程度消耗是在私钥使用的方面。
具体的消耗,需要看加密套件的配置,对AES256-SHA256,这个比例在80%以上,而对ECDHE-AES256-SHA256,这个比例大约是40%。
所以将其独立出来以后,单独在keycenter上使用SSL加速卡,大大提升了SSL加速卡的利用率,同时也大大提升了系统整体服务能力。
为了让证书的私钥等统一管理到SSL-KeyCenter中,并且提供证书整个生命周期的管理,我们还需要另外一个系统Subway来做这些事情。
subway的工作职责:
- 证书管理:证书的申请、有效期管理、配置、签发、证书私钥自动推送KeyCenter集群,部分证书可供下载、证书过期可自动触发替换;
- KeyCenter集群的管控;
- 对统一接入层的集群管控(如果存在);
异地多活,SSL-KeyCenter部署策略
由于KeyCenter中保存了证书的私钥、系统应用的密钥,如果KeyCenter挂了,那么首先通过HTTPS访问来的请求就无法正常解密客户端发来的密文,势必会带来网站的不可用,所以保证KeyCenter的高可用就变的至关重要。
在一些大型公司中,为了提高容灾能力,同城容灾,异地容灾,异地多活已经成为标配,那么KeyCenter会在各个单元机房中进行集群部署。
Keycenter容灾策略主要有以下两个点:
- 对外部请求而言,可以把Keycenter自身使用域名在ADNS上执行流量调度切换;
- 对生产网而言,只允许访问同一IDC内Keycenter集群的内部VIP,不产生跨机房调用,如果某一个IDC出现故障,只需要切走Aserver流量即可。
SSL-KeyCenter在阿里的单个IDC中的部署结构:
SSL-KeyCenter在多机房下的部署:
IDC1中访问KeyCenter目前只能在机房内访问,不能跨机房调用,当IDC1中的KeyCenter全部挂了,则直接从统一接入层中切走整个机房的流量。
疑问:那为什么KeyCenter为什么不能像一般App那样,单机房内服务不可用时,允许跨机房调用呢?
原因:没时间实现,后续会通过VIPServer来动态获取服务机器列表,这样如果单元内服务不可用,就可以允许跨单元调用了。
备注:文章中部分内容非原创,整理资源来源于ATA。