中通密钥管理和在线加解密服务落地经验总结

背景

信息安全从互联网诞生起就是一个绕不开的难题,特别是近年来,中央关于信息安全的政策不断加码,网络安全已上升到国家战略的高度。

图 1 网络安全法律法规

中通作为提供涉及千家万户的快递服务的龙头企业,有义务也有责任积极落实各项法律法规,对用户隐私数据进行安全保护。

为了实现这一工作目标,我们设计规划了完整的数据安全架构,其中密钥管理和加解密服务是基础中的基础,这部分工作从启动到现在已经有两年多时间,在高并发复杂业务生产环境的落地过程中我们踩了不少坑,本着开放共享的初衷,做一些经验总结,供大家参考。

接下来将从安全为本、稳定优先、便捷对接和敏捷扩展四个方面做介绍。

安全为本

作为信息安全类服务,服务本身最基础的要求就是安全。如果提供的信息安全服务本身就是不安全了,那么在此之上建设的服务和和业务就如垒砌的沙塔,随时都可能顷刻崩塌。为了做到安全为本,我们做了如下的设计:

使用安全硬件

软件层面的安全都是受限于其所运行的硬件环境,要搭建一个安全的运行环境就离不开安全的硬件。密钥管理和加解密服务的基石就是经过第三方认证的硬件加密机 HSM(Hardware Security Module)。

使用经过第三方认证的硬件安全模块 HSM(Hardware Security Module)可以帮助业务系统来创建,保护和管理密钥,满足用户多应用多业务的密钥管理需求,同时可以符合监管和合规要求。

在腾讯云和 AWS 的安全模块中也都有相关安全合规要求:“密钥管理系统底层使用国家密码局或 FIPS-140-2 认证的硬件安全模块(HSM)来保护密钥的安全,确保密钥的保密性、完整性和可用性。”

图 2 FIPS-140-2 安全标准

密钥分级

有了安全的硬件设备提供的密钥,并不代表我们的安全基础已经稳固。很多时候不安全的管理会带来毁灭性的破坏,例如:谁都可以获取密钥权限。需要给密钥分级,并给不同级别的密钥设置不同的访问权限。如可进行如下密钥分级:

  • 根密钥(RootKey)

根密钥 (RootKey) 是初始化硬件加密机时通过密钥卡写入的,正常情况下任何人都无法读取和修改这个密钥。

  • 应用主密钥 (AppKey)

应用主密钥 (AppKey) 是创建安全应用 例如:密钥管理系统 KMS(Key Management Service)时,由硬件加密机随机生成并使用根密钥加密的,这个密钥是安全应用服务用于加密或离散,派生工作密钥的。

  • 工作密钥 (WorkKey)

工作密钥 (WorkKey) 是业务系统向密钥管理系统 KMS 申请创建的密钥,是业务系统真正使用的密钥, 使用应用主密钥加密存储,用于应用数据的加密和解密。

  • 传输密钥 (TransKey)

传输密钥 (TransKey) 是 SDK 和应用传递密钥时用于加密工作密钥的随机密钥,这个密钥由应用服务生成并通过非对称加密后传递给 SDK 使用。

  • 信封密钥 (EnvelopeKey)

信封密钥 (EnvelopeKey) 是 SDK 加密数据时生成的随机密钥,这个密钥用于加密 SDK 的待加密数据,信封密钥由工作密钥加密。

为什么要做这么多的密钥层级呢?

因为密钥分级之后可以进行有效隔离和分类管控,不同的层级的密钥做各自的事情,越高级的密钥获取需要更多的授权,对外使用的机会也越少,越低级别的密钥,轮换的频次也越高,被破解后带来的危害也越小。密钥分级后可以系统性地减少底层工作密钥泄漏带来的整体风险。

如使用腾讯云的密钥服务,就会遇到 CMK(用户主密钥) 和 DEK(数据加密密钥),对应到上述分级,CMK 就是工作密钥而 DEK 就是信封密钥。

图 3 腾讯云密钥流控图

图 4 典型密钥流控图

使用安全的算法

不安全的加密,和不加密一样不安全,如 DES、MD5 等已经被破解或者容易破解的安全算法就不建议使用了。推荐使用国密算法 SM2,SM4 或者 AES-256 RSA2 等更安全的算法,腾讯云和阿里云提供的默认 KMS 生成的密钥都已经开始转为国密算法,如下图所示。

图 5 腾讯云默认密钥类型设定

操作审计

在有了硬件和管理的保障之后,还需要提防来自客户端、SDK 和 API 接口的非法访问。你可能说:我们的应用做了各种绑定,我们的接口做了授权。但是如果你的应用被彻底攻陷了呢?你的接口授权信息也可能会被获取,可以像正常应用一样使用你的 SDK 和 API 接口,应该如何防范呢?

那就需要能够对用户的操作进行最小权限管控和操作审计。通过接入 SSO 记录用户的行为来保证数据操作可溯源可审计,如腾讯云或者 AWS 是与访问管理(CAM)集成,通过身份管理和策略管理控制账号对 CMK 的访问权限。如图 6

图 6 AWS 密钥访问权限控制流程图

  • 记录用户的行为

首先当然是要记录用户的操作记录,例如: SDK 或 API 接口的调用时间,地点,设备,频次。把这些数据记录到 ES 或者数据库中。

  • 统计分析用户的行为

有了用户的行为后,就可以分析这些操作是否合理?例如一个低频使用的应用调用,调用频率是否过高了?在业务低峰期是否有大量的的请求涌入。有了足够的数据之后就可以设计异常行为分析模型来进行检测。

  • 智能风控和告警拦截

通过结合用户行为分析结果和服务调用透传的身份等原始数据,就可以为用户评估风险等级,实现智能风控和告警拦截等功能。

稳定优先

一套基础服务在保证了自身的安全之后,最重要的就是高可用 H.A.(High Availability)。由于安全服务是所有应用使用的基础服务,它的稳定性能影响所有的上层应用,如何保障安全服务的高可用呢?

保持冗余

硬件加密机 HSM 和相关服务的数据库等基础组件实现多机房热备。数据库实现主从分离和异地热备,确保从数据库可以快速切换到异地机房的热备数据库上,如果切换后主库无法写入也可以保证在安全服务的高可读(密钥管理和加解密服务本质上是一个强读弱写的应用)。

在保证硬件加密机和数据库的冗余之外还要保证网络组件的冗余,例如负责服务接入的负载均衡、交换机和路由器等。

服务解耦

安全基础服务为了保证自身的高可用还需要尽量的和外部应用解耦,最好做到就是外部都不可用的情况下还能继续对外提供服务。保持数据库冗余的设计其实已经实现了和数据库解耦,并且数据库做到异步写入,在安全服务启动时就预加载所有的密钥信息,只要服务能正常启动,最基础的密钥查询和数据加解密等功能就能运行。

多层降级

服务端做到了保持冗余和服务解耦后就可以高枕无忧了么?显然还是不够的,例如由于网络故障,直接无法访问服务器了咋办?因此还需要在 SDK 中做多层降级。

  • 多域名降级

在生产环境为不同机房配置多个域名,SDK 会在主机房不可达时尝试降级到备份域名,这可以保证在一个机房不可用时降级到其他机房,利用负载均衡可以实现自动降级处理,自动切换机房。

  • 动态库本地降级

如果所有机房都不可用时,还可以降级到本地动态库。在设计 SDK 时可以规划本地安全动态库,在 SDK 启动时,本地动态库会把使用公私钥行服务端获取本机需要使用的最小密钥集合,加密存放到内存中。当所有的远程方案都异常时,就可以使用本地动态库初始化时的密钥,来实现本地加解密。在不重启服务的情况下,SDK 只要注册成功后就可以脱机运行。

整体的系统架构如下图所示:

图 7 典型密钥服务整体架构图

弹性扩容

通过 promethus 和 grafana 来监控整体负载,当服务容量达到 60% 就需要及时扩容机器,通过 K8s 使用容器技术可以快速部署生产环境并实现弹性扩容。

便捷对接

有了安全基础服务,推动现有系统进行对接将会是一个更大的挑战。如何让各个团队能便捷对接呢?

支持多种接口类型

多接口类型的支持是现在大多数 SDK 的标准做法,腾讯云和 AWS 密钥中心都支持多种开发语言的 SDK 接入。如最通用的是 java sdk,最便捷的是使用 dubbo 方式接入服务,此外还可以根据实际情况支持 python 和 golang 等语言的对接 SDK。

集成到公司研发框架

将 SDK 集成到公司的开发框架无疑是一个不错的选择,特别是可以集成到 mybatis 的 plugin 中,直接实现数据库中的字段加密。

支持灰度调用

由于公司业务系统相对复杂,一条产线的上下游包含了多个系统,不同系统的对接进度往往无法管控,如果上游应用还没对接好,下游应用就无法继续,这种情况也是推广过程中必然会遇到的难度。因此支持灰度调用,也是便捷对接的重要一环,如上游数据还没有对接加解密服务,但是下游系统已经支持数据解密,如果需要下游系统判断数据是否加密再判断是否需要调用解密,显然会增加下游系统开发的压力,这些硬编码的代码也是不优雅的代码污染。

支持灰度,使用方在解密数据时,无需判断字段是否加密,将会使得对接更加流畅。

灰度流程如下图所示:

图 8 典型密钥服务灰度流程图

提供接口文档和示例

最后就是完整的接口文档和示例,完善的文档和示例,可以大大减少服务推广的难度。很多时候一段简洁的示例,可以让用户快速明白如何对接,如何上手。

敏捷扩展

做一套服务很容易,做好一套服务并真正用起来很难。

用户的需求总是在变,在确保服务稳定的基础上做好服务的敏捷扩展,是提升用户体验的一种好方式。如何做好敏捷扩展呢?

主动发现需求

很多时候开发者并不知道用户是如何使用我们的产品的,这就考验我们通过用户行为去主动发现用户需求的能力。如初始阶段 SDK 注册启动时需要用户主动上报服务器 IP 加白名单,服务容器化之后 IP 变成无法管控,就发现用户自己做了个微服务来固定 IP 代理请求。这种方式不利于负载均衡,这时可以主动找到用户并了解场景,让 SDK 实现动态绑定 IP。另外在测试环境一台服务器上实例化了多个客户端,出现了只有最后启动的实例可以正常运行的 bug,通过这个 bug 我们扩展了单一主机多实例绑定的功能。

及时反馈和满足新需求

在对接时需要对用户的需求做出及时反馈,能提需求的用户才是天使用户,如对固话的支持、密文数据的模糊查询、批量加密和批量解密的数据格式等,都是用户提出的需求转化过来的功能特性。   

写在最后

本文简单介绍了中通密钥管理和在线加解密服务的相关经验总结,从安全为本、稳定优先、便捷对接和敏捷扩展四个方面做了整体介绍,相关技术细节不便具体展开,感兴趣的朋友可以线下做进一步的技术交流。


原文地址 mp.weixin.qq.com

文章作者:  BigYoung
版权声明:  本网站所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 BigYoung !



z