当您的自建应用程序需要加密大量数据或者您不希望上传数据到阿里云密钥管理服务KMS(Key Management Service)时,可以使用信封加密。本文介绍如何使用KMS实现对数据的信封加密。
适用的密钥类型
软件密钥、硬件密钥。
软件密钥、硬件密钥、默认密钥中的服务密钥和主密钥均可进行信封加密,但默认密钥中的服务密钥和主密钥仅用于云产品服务端加密,不能用于用户自建应用加密,软件密钥、硬件密钥不仅可用于云产品服务端加密,也可用于用户自建应用加密。
本文仅介绍用户自建应用进行信封加密的场景,关于云产品服务端加密,请参见云产品集成KMS加密概述。
什么是信封加密
KMS信封加密是类似数字信封技术的一种加密手段。使用KMS信封加密时,KMS为您生成数据密钥并使用您的KMS密钥对数据密钥进行加密,然后将数据密钥明文和密文安全地传递给您的应用程序。您的应用程序使用数据密钥明文来加密数据,并将数据密文和数据密钥密文存储起来。解密数据时,应用程序首先请求KMS对数据密钥密文解密得到数据密钥明文,然后使用数据密钥明文对数据密文解密。
信封加密流程
应用程序通过KMS实例SDK调用GenerateDataKey接口生成数据密钥,然后通过第三方密码算法库或密码模块产品使用数据密钥对数据进行加密,最后将数据密钥密文作为信封和数据密文组装在一起。具体流程见下图。
应用程序调用GenerateDataKey接口,传入如下信息用于生成数据密钥。
KeyId:您创建的密钥的KeyId或别名。
NumberOfBytes:数据密钥的长度。从安全角度考虑,推荐您设置为24字节及以上长度。
说明常用的对称加密算法中,AES算法加密需要16字节、24字节或32字节的数据密钥,3DES算法加密需要16字节或24字节的数据密钥。
应用程序收到KMS返回的数据密钥,其中包含数据密钥明文、数据密钥密文、加密参数(包含加密算法以及加密后的初始向量IV)。
数据密钥密文是由GenerateDataKey接口中传入的密钥加密数据密钥明文生成的,其中加密模式为GCM。
应用程序使用数据密钥明文在本地对数据进行加密得到数据密文。
重要使用数据密钥明文在本地对数据进行加密、解密时,您可根据应用程序语言的适用性、安全合规方面的要求自主选择第三方密码算法库或密码模块产品。
使用数据密钥明文加密完成后,请您及时将数据密钥明文销毁。
应用程序将数据密文、数据密钥密文、KMS的密钥(即用于生成数据密钥的密钥)和加密参数(包含生成数据密钥时的加密算法以及IV)进行保存。
信封解密流程
应用程序通过KMS实例SDK调用Decrypt接口解密数据密钥密文,得到数据密钥明文,然后通过第三方密码算法库或密码模块产品使用数据密钥明文对数据密文进行解密,得到数据明文。具体流程见下图。
应用程序读取数据密文、数据密钥密文、KMS的密钥(即加密数据密钥的密钥)和加密参数(包含生成数据密钥时的加密算法以及IV)。
应用程序调用KMS的Decrypt接口并传入上一步读取的信息,用于解密数据密钥密文。
应用程序收到KMS返回的数据密钥明文。
应用程序使用数据密钥明文在本地对数据密文进行解密,得到数据明文。
应用场景
典型场景包括(但不限于):
用户自建应用程序加密多个业务数据文件,且每个数据文件需要使用不同的数据密钥。
需要加密多份数据文件且数据量很大时,如果使用单个或少量密钥直接加密这些数据,会增加密钥被破解的风险。通过采用KMS信封加密技术,分别使用新生成的数据密钥来加密各份数据,仅使用您在KMS中的密钥来加密数据密钥,很大程度提升加密方案安全性。
用户自建应用程序单次加密大量数据,例如:全磁盘数据。
单次加密数据量巨大时,如果由业务应用服务器通过网络安全信道传递到KMS,由KMS加密后再返回给用户,大量的数据网络传输会带来较高的成本和延时,使用信封加密可以解决这些问题。
使用限制
用户自建应用程序通过KMS进行信封加密时,仅可使用软件密钥管理实例或硬件密钥管理实例中的对称密钥,可选择的密钥规格如下。
软件密钥管理实例:Aliyun_AES_256。
硬件密钥管理实例:Aliyun_AES_256、Aliyun_AES_192、Aliyun_AES_128或Aliyun_DES3_192。
准备工作
已创建应用接入点AAP。具体操作,请参见创建应用接入点。
已安装KMS实例SDK。具体操作,请参见KMS实例SDK for Java、KMS实例SDK for PHP、KMS实例SDK for Go或KMS实例SDK for Python。
应用开发示例
示例代码中数据密钥采用32字节(256位)的AES密钥,且对数据进行加密时采用GCM加密模式。
Java
示例中使用SunJCE Provider密码库对数据加密、解密 。
信封加密,请参见信封加密示例代码。
信封解密,请参见信封解密示例代码。
Python
示例中使用cryptography.hazmat密码库对数据加密、解密。
信封加密和解密,请参见信封加密和解密示例代码。
Go
示例中使用golang/crypto密码库对数据加密、解密。
信封加密和解密,请参见信封加密和解密示例代码。
PHP
示例中使用OpenSSL密码库对数据加密、解密。
信封加密和解密,请参见信封加密和解密示例代码。