前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次国密落地的经历

记一次国密落地的经历

作者头像
Kevinello
修改2022-12-01 19:57:23
1.2K0
修改2022-12-01 19:57:23
举报
文章被收录于专栏:Kevinello的技术小站

前言

在一般意义上的后台服务中,身份认证可以保证数据源没有问题,完整性校验可以保证数据没有经过窃听者的篡改,但我们还要防止窃听者知道数据的内容,这就还需要加解密来帮助我们守住最后一道围墙

而在私有云交付的环境中,我们无法用现有的公司平台加解密服务,并且按照国家、金融行业等要求,需要用国密算法实现的加解密方案

国密存在哪些问题

使用不便

最大问题是使用不便。这是由于国密不在IETF国际标准中,不同于ECDSA、ECDH、RSA等国际算法,系统中往往包含相关标准加解密方式,业务数据包通过HTTPS传输时完全不用考虑如何交换公钥,如何加解密数据。

因此现阶段使用国密必须在业务层手动进行数据加解密,相当于对数据进行一步额外的操作。

无最佳实践

确定业务层进行加解密后,应该使用哪一种国密实现、该如何进行加解密是另一个难点,且暂不存在一个最优解。国密的实现方案很多,包括TencentSM、GmSSL和KMS服务器,这也需要进一步的调研和测试来决定最终方案。

国密落地过程

国密落地分为调研、制定、实现与测试四个阶段。

调研阶段主要目的有两个:

  • 找到性能高效、使用便捷并且有足够保障(维护活跃度、大厂背书、有变现渠道保证不会暴死等)的国密算法实现
  • 调研公司内国密改造案例

国密算法选择

我们通过benchmarks测试评估多种国密库算法性能,最终结果如下:

可以看到TencentSM的benchmarks测试结果较为突出,也是作为我们的最终选择

国密实现方案选择

对于国密的实现,我们收集到的可行方案如下:

  1. XX实验室建议方案:引入额外KMS系统,独立部署管理证书、私钥,分发公钥。
    • 优点:保密性好,完整的加解密方案(包括证书、信任链等待)
    • 缺点:需要在业务侧缓存大量SM4密钥,对性能有影响
  2. XXX网关团队数据加密方案:一次链接一个SM4密钥,发送SM4加密的数据同时发送SM2公钥加密后的SM4密钥。
    • 优点:过程简单
    • 缺点:服务端每次数据处理都需要双解密(解密密钥后解密数据),对性能有影响
  3. 无侵入数据加密方案:使用双SSL证书(RSA/SM2)的HTTPS前置机作为网络入口,完全无侵入性地替换。
    • 优点:完全无缝地替换国际加密协议,业务侧无感知
    • 缺点:SDK侧同样需要双证书支持,但目前普遍缺乏实现;需要添加额外组件HTTPS前置机

在制定方案之前,我们总结了对解密方案的需求:

  1. 简单无依赖
  2. 性能好
  3. 成熟
  4. 支持服务器热更新SM2公钥
  5. 支持上报失败后数据加密落地重传

可以接受的缺点:

  1. 对业务侵入

于是在制定方案时我们充分考量了HTTPS加解密方式,设计了类似的加密上报方式

基于对称密钥加密公钥的非对称加密方案,时序图如下:

代码语言:javascript
复制
  sequenceDiagram
    participant S as SDK
    participant E as Entrance
    participant A as AppConfig
    Note over E: 获取或生成SM2钥匙对
    E->>+E: SM2钥匙对
    S-->>E: requestForPubKey()
    E->>S: 返回SM2公钥
    Note over S: 若错误,停止后续
    S-->>E: 请求token
    E->>S: token
    S-->>A: requestForConfig()
    A->>S: 返回配置
    Note over S: 若错误,停止后续
    loop 上报数据
        S->>+S: 生成临时SM4钥匙
        S->>E: uploadEncryptedJson()/uploadEncryptedFile()
        alt 上报成功
            E->>S: 成功
            Note over S: 啥也不干
        else 上报成功但公钥需更新(1507)
            E->>S: 返回最新SM2公钥
            Note over S: 更新本地公钥
        else 解码失败(1508)
            E->>S: 返回最新SM2公钥
            Note over S: 抛弃所有数据,更新公钥
        else Check-Code校验失败(1509)
            E->>S: 无
            Note over S: 不应该在正式SDK发生
        else 上报失败
            E->>S: 失败
            Note over S: 缓存数据、落盘(md5、加密后钥匙(16进制字符串)、iv、加密后数据)
        end
        S->>-S: 销毁临时SM4钥匙
    end
    E->>-E: SM2钥匙对

值得注意的是:

  1. 为了确保解密后数据无误,同时上报原始数据MD5用以比对
  2. 为了确保服务器更新SM2公钥后上报仍然可以进行,我们设计了主从密钥方式,被换下的密钥并不删除,而是作为从钥继续用以解密,并且通知终端更新公钥
  3. 为了确保上报失败后可以重试,我们将加密数据以及meta信息落盘

该方案经过云鼎实验室同事确认可靠性,我们最终采取了该方案

重难点解决

高并发下的解密实现

由于解密过程需要用到线程相关的变量,若每次解密都去生成对应的上下文将非常耗时。同时由于在QAPM的国密方案下公钥是定期更新的,所以这里为了保证解密流程的性能,在初始化时使用SM2InitCtxWithPubKey为每一个Worker创建了一个上下文。

代码语言:javascript
复制
/**
 * @brief 使用SM2获取公私钥或加解密之前,必须调用SM2InitCtx或者SM2InitCtxWithPubKey函数.如果使用固定公钥加密,可调用SM2InitCtxWithPubKey,将获得较大性能提升
 * @param ctx  函数出参 - 上下文
 * @param pubkey  函数入参 - 公钥
 */
func SM2InitCtxWithPubKey(ctx *SM2_ctx_t, pubkey []byte) {
 if ctx == nil || pubkey == nil {
  panic("invalid parameter")
 }
 if len(pubkey) < 130 {
  panic("memory len is too small")
 }
 C.SM2InitCtxWithPubKey(&ctx.Context, (*C.char)(unsafe.Pointer(&pubkey[0])))
}

再通过自行实现的协程池管理并发解密任务,兼顾解密服务的稳定性和吞吐量。

代码语言:javascript
复制
type Worker struct {
 name    string
 ctx     *sm.SM2_ctx_t // ThreadLocal ctx
 handler WorkerHandler
}

避免国密接口对原有架构的侵入性

由于实现的国密方案是在项目原有的接入层微服务代码中拓展实现,为保证原有架构的完整性,避免国密接口侵入导致的额外开发量以及额外的维护成本,我们对接入层的架构进行了微调,最终通过重写fasthttp的部分方法(如BodyGunzip, MultipartFormBoundary, MultipartForm, Body等),细化对request的处理步骤,完全解耦了解密和接口具体逻辑

耗时监控

最终上线符合国密标准的接入层系统后,构建耗时监控如下:

可以看到耗时在可控范围内,且除文件上报外耗时无明显变化

总结

安全无小事,这是我第一次参与大型的加解密服务的设计与实现工作中,希望后续还会有机会丰富我浅薄的网络安全知识🤔🤔🤔

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 国密存在哪些问题
  • 国密落地过程
    • 国密算法选择
      • 国密实现方案选择
      • 重难点解决
        • 高并发下的解密实现
          • 避免国密接口对原有架构的侵入性
          • 耗时监控
          • 总结
          相关产品与服务
          SSL 证书
          腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档