你在工作中遇到的最困难的模块是什么

98 阅读11分钟

前言

在一次常规的Java面试中,“请讲述一下你遇到的困难的模块”恐怕是非常常见,以下是我为此做的一次准备。根据一个加解密平台做了总结。

讲述一下困难的模块

我认为我碰到的最复杂的模块是加解密模块,出于业务上的需求,客户对数据的传输和储存的安全性有很高要求,在研发过程中团队遇到了如下问题:

  1. 密钥(包括非对称加解密证书)保存在源文件或者配置文件中,存储分散而不安全
  2. 密钥没有分片交换机制,不能满足高安全级密钥管理和交换的要求。
  3. 密钥缺乏版本管理,不能灵活升级,一旦修改密钥,此前加密的数据就可能无法解密
  4. 加密解密算法程序不统一,同样算法不同实现,内部系统之间密文不能正确解析。
  5. 部分加解密算法程序使用了加解密算法和密钥,存在安全隐患。

【1】密钥和算法的存储问题

为了解决上述问题,团队最终决定研发一个密钥管理系统,在该系统上存放和管理加解密算法和密钥,应用程序只需要依赖加解密服务SDK,调用接口进行加解密即可,而真正的算法和密钥在系统服务端进行管理,保证算法和密钥的安全。

【2】密钥的分片交换机制

密钥将被分片存储在文件服务器(Key File Store)和数据库服务器(Key DB)中,每个服务器都由不同的人负责管理,每个人各司其事,没有人能查看完整的密钥信息。所以密钥管理系统中部署了密钥管理组件(Key Manager),用于访问数据库中的应用程序密钥元信息(Key Meta Data),以此获取密钥分片存储信息。密钥管理系统根据这些信息访问File StoreDB,获取密钥分片,并把分片拼接为完整密钥,最终返回给SDK

大体的角色:

  1. 开发工程师使用密钥管理功能为自己开发的应用申请加解密算法和密钥;
  2. 安全工程师使用密钥管理功能审核算法和密钥的强度是否满足数据安全要求;
  3. (经过授权的)密钥管理者使用密钥管理功能可以查看密钥(的一个分片)。

【3】密钥的版本管理

为了对密钥进行版本管理,我们设计了一个密钥领域模型

  1. 一个应用程序使用的所有密钥信息都记录在KeyBox对象中,KeyBox对象中有一个keySuitMap成员变量,这个mapkey是密钥名称,value是一个KeySuit对象;
  2. KeySuit类中有一个keyChainMap成员变量,这个map类的key是版本号,value是一个KeyChain对象。项目因为安全性需求,需要支持多版本的密钥。也就是说,对同一类数据的加密密钥过一段时间就会进行版本升级,这样即使密钥泄露,也只会影响一段时间的数据,不会导致所有的数据都被解密;
  3. KeySuit类的另一个成员变量currentVersion记录当前最新的密钥版本号,也就是当前用来进行数据加密的密钥版本号。而解密的时候,则需要从密文数据中提取出加密密钥版本号(或者由应用程序自己记录密钥版本号,在解密的时候提供给SDK API),根据这个版本号获取对应的解密密钥;
  4. 具体每个版本的密钥信息记录在KeyChain中,包含了密钥名称name、密钥版本号version、加入本地缓存的时间cache_time、该版本密钥创建的时间versionTime、对应的加解密算法algorithm,当然,还有最重要的密钥分片列表keyChipList,里面按序记录着这个密钥的分片信息;
  5. KeyChip记录每个密钥分片,包括分片编号no,以及分片密钥内容chip

image.png

【4】密钥的高可用性

除此之外,密钥管理器还应该具备高可用的特性。如果密钥管理服务器临时宕机,或者网络通信中断,也不会影响到应用程序的正常使用。我们借助了缓存机制,密钥缓存在SDK所在的进程(也就是应用程序Apps所在的进程)中,只有第一次调用时会访问远程服务器,其他调用只访问本进程缓存。因此加解密的性能只受加解密的数据大小和算法的影响,不受远程服务的性能影响,满足了性能要求。

但是如果密钥管理服务器长时间宕机,此时应用重新启动,本地缓存被清空,就需要重新请求密钥,这时候应用就不可用了。为解决该问题,需要对密钥管理服务器、数据库和文件服务器做高可用备份。密钥管理器服务器部署2-3台服务器,构建一个小型集群,SDK通过软负载均衡访问密钥管理服务器集群,若发现某台密钥管理服务器宕机,就进行失效转移。同样,数据库和文件服务器也需要做主从备份。

基础知识储备

加解密算法都有哪些

加解密算法从大类上分为对称加密、非对称加密、摘要加密、消息认证、签名和验证、URL编码等等;

  1. 对称加密主要分为:AESDESSm4三种,特点是加解密都使用一个秘钥;
  2. 非对称加密主要分为:SM2RSA等等,特点是使用两个秘钥,一个加密一个解密;
  3. 摘要加密主要分为:MD5SHA1SM3等等,特点是不可逆;
  4. 消息认证和摘要思路类似,区别是有一个秘钥;
  5. 签名和验证一般采用RSA,所以需要一对秘钥;
  6. URL编码是前后端数据传输解决中文乱码或浏览器未知字符的常用手段。

什么是强/弱加解密算法/密钥

弱加密算法有:

  1. 哈希算法:MD4MD5SHA1,可使用SM3替代
  2. 对称加密算法:DESAES CBC模式、AES ECB模式,可使用SM4AES CBC模式+HMAC替代
  3. 非对称加密算法:RSA1024RSA nopadding,可使用SM2SM9RSA2048(需要使用RSA_PKCS1_OAEP_PADDINGOAEPPadding)替代

弱密钥指的是容易被破解的密码,如“123456”等非常常用的密码。强密码规则:密码要包含包含数字、字母和特殊字符,长度要求8以上。

什么是SM4算法

SM4是国产的对称分组加密算法,通过128位的密钥对数据进行加密或解密,其特点是效率高,适合硬件实现。特别是在移动通信和物联网等场景中,它的使用日益广泛。

SM4的加解密过程

SM4算法的加密过程,分为明文分块、密钥扩展、轮加密、输出状态、返回密文五个步骤:

  1. 明文分块:将输入的明文分成每个8字节(64位)一块,存储在名为cipher的字符串数组中的前四个元素中。
  2. 密钥扩展:调用KeyExtension函数生成轮密钥,将生成的轮密钥存储在名为rks的字符串中。
  3. 轮加密:循环执行32轮的加密操作。在每一轮中,进行一系列的XORT运算,然后将结果存储在cipher数组中的相应位置。
  4. 输出状态:在每一轮加密后,输出当前轮轮密钥和输出状态。
  5. 返回密文:最后,将最后一轮的输出状态连接起来,形成最终的密文,并将其作为函数的返回值。

SM4算法的解密过程,分为密文分块、密钥扩展、轮解密和输出状态、返回明文五个步骤:

  1. 密文分块:将输入的密文分成每个8字节(64位)一块,存储在名为plain的字符串数组中的前四个元素中。
  2. 密钥扩展:调用KeyExtension函数生成轮密钥,将生成的轮密钥存储在名为rks的字符串中。
  3. 轮解密:循环执行32轮的解密操作。在每一轮中,进行一系列的XORT运算,然后将结果存储在plain数组中的相应位置。
  4. 输出状态:在每一轮解密后,输出当前轮的轮密钥和输出状态。
  5. 返回明文:最后,将最后一轮的输出状态连接起来,形成最终的明文,并将其作为函数的返回值。

SM4的工作模式是什么

SM4的核心加密过程是基于分组的,但在实际应用中,数据往往不是单个固定的128位分组,因此需要结合不同的工作模式来处理任意长度的数据块。工作模式定义了如何将数据分块,并控制加密块之间的依赖性。

SM4都有哪些工作模式

  1. ECB( 电子密码本模式 ECB将明文划分为独立的128位分组,对每个分组独立进行加密。它简单但安全性较低,适合结构化数据。
  2. CBC( 密码分组链接模式 ):CBC 通过引入链式依赖来提高安全性。它将每个明文块与前一个密文块异或后再进行加密,第一个分组需要一个初始化向量(IV)来开始链式加密。它具有良好的安全性,适合大多数应用。
  3. CFB( 加密反馈模式 CFB是一种流模式,允许加密不满128位的数据块。CFB的基本思想是,先将初始化向量加密,然后将输出与明文进行异或操作生成密文。
  4. OFB( 输出反馈模式 OFBCFB类似,但加密过程不依赖于前一个密文块。OFB通过将上一个加密结果作为输入,生成伪随机流。
  5. CTR( 计数器模式 ): 通过计数器生成伪随机流,每个分组的加密是独立的,因此可以并行处理,且是安全的。
  6. GCMGCM是一种结合了CTR模式和身份验证的加密模式。它提供了加密和认证功能,适合对数据进行加密时也需要验证数据完整性(对安全性要求极高)的场景。

什么是SM2算法

SM2算法是国产的非对称加密算法,采用椭圆曲线密码体系,适用于数字签名、密钥交换和公钥加密等场景。

SM2算法的主要特点如下:

  1. 安全性高:SM2算法基于椭圆曲线离散对数问题,具有较高的安全性。
  2. 算法效率高:SM2算法的计算量相对较小,适合在资源受限的环境中使用。
  3. 适用性广泛:SM2算法可用于数字签名、密钥交换和公钥加密等多种密码应用场景。
  4. 算法标准化:SM2算法已被国际电信联盟(ITU-T)和国际标准化组织(ISO)认可为国际标准。

SM2的算法步骤

  1. 密钥生成: 首先,选择一个椭圆曲线和基点。然后,用户随机生成一个私钥,并计算公钥。
  2. 加密:使用公钥加密原文
  3. 解密:使用私钥解密密文
  4. 签名:使用私钥对数据进行签名
  5. 验签:使用公钥验证签名

业务相关问题

你的数据都各自用了什么加密方式

  • 姓名、证件号码、手机号等敏感数据使用SM4对称加密;
  • 前后端接口数据传递使用SM2非对称加密。
  • 前端向后端数据传输先进行URL编码,后端接收数据后URL解码。

非对称加密在你的项目中有什么作用

  1. 安全通信:数据传输过程中不被窃取或篡改。
  2. 密钥交换:适用于需要双方分别保管密钥的场景。
  3. 数字签名:创建数字签名,验证文件或消息的完整性和来源的真实性。