# KMS SDK 接入文档
# 使用对象
接入KMS的应用平台相关人员
# 版本信息
| 版本信息 | 修订时间 | 修订人 | 修订内容 |
|---|---|---|---|
| 3.3 | 2023-03-26 | SIMKEY团队 | 初始版本 |
# 术语及缩略语定义
下列术语、定义和缩略语适用于本标准:
| 名词 | 解释 |
|---|---|
| API | Application Programming Interface,应用程序编程接口 |
| SDK | SoftwareDevelopment Kit,软件开发工具包 |
| 对称加密算法 | 对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法 |
| 非对称加密算法 | 加密和解密使用不同密钥的加密算法,也称为公私钥加密算法 |
| 哈希算法 | 散列函数(英语:Hash function)又称杂凑函数/算法、散列函数/算法、哈希函数/算法,把任意长的输入消息串变化成固定长的输出串的一种函数。在密码学中,散列函数必須具有不可逆性。 |
| 国密算法 | 国家密码局认定的国产密码算法,主要有SM1,SM2,SM3,SM4,SM7,SM9,祖冲之密码算法(ZUC)等等。其中SM1、SM4、SM7、祖冲之密码(ZUC)是对称算法;SM2、SM9是非对称算法;SM3是哈希算法。 |
| MAC | 消息认证码,密码学中,通信实体双方使用的一种验证机制,保证消息数据完整性的一种工具 |
| HMAC | HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,是一种基于Hash函数和密钥进行消息认证的方法,能提供 消息完整性认证 和 信源身份认证 两方面的消息认证 |
| SM3HMAC | 基于SM3 hash 算法的HMAC算法 |
# 产品架构图
KMS分为服务端和客户端SDK
KMS服务端使用有国密资质的加密卡或者加密机生成并加密保护密钥,也提供加解密的能力
KMS SDK通过以太网协议与KMS服务端通讯,实现密钥生成,远程加解密等
# 密钥与存储
在本系统中,密钥根据使用方式分为两种:加解密密钥和hmac密钥;密钥根据使用对象分也为两种类型:业务密钥和用户密钥。
加解密密钥 加解密密钥是在加密、解密时使用的密钥,用于保护敏感数据。
Hmac密钥 Hmac密钥是在计算hmac时使用的密钥,hmac用于保护数据的完整性。
业务密钥 业务密钥为业务系统使用的密钥,包括业务加解密密钥和业务hmac密钥。业务密钥在kms平台保存,只给KMS SDK返回密钥id, 需要应用方将 密钥id 保存到数据库。
用户密钥 用户密钥为每个用户使用的密钥,包括用户加解密密钥和用户hmac密钥。用户密钥在kms平台不保存,通过KMS SDK返回 密钥id 和 密钥密文,需要应用方将返回的 密钥id 和 密钥密文 保存到数据库。
业务密钥是系统级别的密钥,主要作用有两个:
1、用于保护系统级别的数据,加解密系统级别的数据
2、用于保护用户密钥(数据密钥)
因此一个业务系统只能有少量的业务密钥,业务系统在调用SDK API生成业务密钥后,会得到业务密钥ID,且需要保存。可使用业务密钥ID调用SDK API接口进行加解密系统级别的数据,不建议使用业务密钥进行用户级别的数据加解密。
用户密钥是用户级别的密钥,主要作用:用于保护用户级别的数据,加解密用户级别的数据。
因此建议为每个用户生成属于该用户的用户密钥,根据业务设计需要,每个用户可以有多个用户密钥,用于保护不同业务数据, 如可以为每个用户生成一个用于保护用户信息的用户密钥,也可以为每个用户生成一个用于保护订单信息的用户密钥,但业务系统要维护用户的密文数据 和密钥的对应关系。
# 输出格式
长格式是输出的密文长度比较长, 长格式使用随机向量, 且将密钥信息等更多的冗余信息记录进去了, 更安全, 也更加完善.
短格式是输出的密文长度比较短, 使用固定的向量.
故使用长格式输出时, 每次加密结果都不一样, 故无法用于有搜索的情况
比如一个16字节的数据
使用业务密钥长格式加密后的结果是 :
MGwCAQECAgQCAQH/BCB4a7HXJhA/1jKdAd5/EwEIWhH+v5ECceUi4FDnF2g9zaASBBAiaKo5TEdJYLrzz9rt+m/AoRIMEDA0NjFFM0JFRjY1NTUwMDeiCgwIM0ZDNTVFNDSjCgwIMTEwMTUwMDA=
字符串长度是148
使用业务密钥的短格式加密后的结果是:
453.0.1.Xv29bFGl1IdX+psJCyPc+2qf2HaSe3388RiO42BrQsE=
字符串长度是52
使用用户密钥长格式加密结果是:
MIHSAgECAgIEAgEB/wQgS00dc/dNW2u/1UTOP7X1WJd1u6AtxsGjjx8o3C19+h6gEgQQESIzRFVmd4gRIjNEVWZ3iKESBBC8T5pg59VHVq4/jH46NG9xowoMCDExMDE1MDAwpXAEbjBsAgEBAgIEAgEB/wQgIlk02IpPjQmfOneBPcOXoGM3AIu8n/feDVoVI9OJLj2gEgQQkvMmufHdt/VbspRg5K0n2qESDBBERTJCN0IxNTIwNDUzNTU4ogoMCDNGREVFNjUzowoMCDExMDE1MDAw
字符串长度:284
使用用户密钥短格式加密结果是:
MFQCAQICAgQCAQH/BCAKgj2GbuHVroLsiVEY2Ch4ZtQnwTwW7anJcbPr3oYnQaASBBARIjNEVWZ3iBEiM0RVZneIoRIEEA9Pb7H2p0dWqKTcVsLsDpc=
字符串长度:116
| 原文字节长度 | 16 | 50 | 100 | 150 | 200 |
|---|---|---|---|---|---|
| 业务密钥长格式 加密结果字符串长度 | 148 | 192 | 256 | 320 | 388 |
| 业务密钥短格式 加密结果字符串长度 | 54 | 98 | 162 | 226 | 290 |
| 用户密钥长格式 加密结果字符串长度 | 284 | 328 | 392 | 460 | 524 |
| 用户密钥短格式 加密结果字符串长度 | 116 | 160 | 224 | 288 | 356 |
根据上面的统计信息大约可以得到计算公式:
业务密钥长格式 加密结果字符串长度 ≈ 1.3x字节长度 + 127
业务密钥短格式 加密结果字符串长度 ≈ 1.3x字节长度 + 33
用户密钥长格式 加密结果字符串长度 ≈ 1.3x字节长度 + 263
用户密钥短格式 加密结果字符串长度 ≈ 1.3x字节长度 + 95
系数1.3 是将byte[] 格式的的数据转为base64编码字符串 导致的, 更精确的是 1.3333333... 而后面的常数是加的冗余信息
两者对比
| 长格式 | 短格式 | |
|---|---|---|
| 优点 | 加密时用到的加密卡的密钥ID等信息被包含在密文当中, 密文有很多信息, 格式完备 | 短 占用较少的存储空间 |
| 缺点 | 比较长, 占用较多的存储空间 | 有部分加解密信息比如 IV 等是存储在平台的, 每次加密KMS平台都会产生一些相关的数据存储在平台, 对KMS平台压力较大 因为需要平台的帮助,所以短格式只能是在业务密钥中使用 |
# IV自动生成的策略
在使用业务密钥和用户密钥做对称加解密时,
长格式使用随机生成的IV
短格式使用相同的IV. 业务密钥使用的IV在平台配置, 默认会预置一个; 用户密钥使用的IV是根据密钥信息和算法推导出来的一个值, 同一个密钥得到相同的IV, 不同的密钥得到不同的IV.
# 简易解密
常规用法需要先找到业务密钥id或者用户密钥,构造对应的对象后进行解密操作,由于我们定义了一个密文的结构,可以从密文中解析出当时加密用的密钥信息,故使用简易解密接口可以不用找到用到的密钥信息而进行解密,方便使用
| 长格式是否支持简易解密 | 短格式是否支持简易解密 | |
|---|---|---|
| 业务密钥 | 是 | 是 |
| 用户密钥 | 是 | 否 |
故推荐在业务密钥中使用短格式, 用户密钥看情况而定