透明数据加密(Transparent Data Encryption (简称TDE))是指可以在文件层对数据和文件进行实时加密和解密,落盘的文件是加密后的内容,而对于上层应用系统和开发人员而言,加解密过程是无感知的,写入和读取的内容是明文内容,所以叫做透明数据加密。长安链密码模块同时提供了软件实现和硬件集成,使用以下步骤即可完成TDE的配置。
长安链的透明数据加密默认支持AES和国密SM4两种对称加密算法。AES算法支持128位、192位、256位这3种密钥长度,SM4算法支持128位密钥长度。密钥长度必须与对应的算法匹配,如果长度不匹配则无法正常启动长安链。我们以国密SM4算法为例,密钥推荐使用随机密码生成器生成的密码,比如“0H#y@EGXPOAScAnB”这样的形式,将有效提高数据的安全性,防止被字典破解。除了字符串形式的密钥,长安链还支持任意二进制形式的密钥,只要长度满足要求(国密SM4:128位)即可。新生成的密钥请做好安全备份,防止密钥丢失后数据无法解读。
在长安链节点的配置文件,即chainmaker.yml文件中,storage配置项下提供了对该节点TDE的配置选项,形如:
- storage:
- encryptor: sm4 # sm4/aes
- encrypt_key: "1234567890123456" #16 bytes key
encryptor是采用的对称加密算法,目前支持sm4和aes两个选项。
encrypt_key是对称加密的密钥,支持字符串、十六进制和文件路径三种形式。
字符串,支持字母大小写、数字、符号、空格等,长度必须满足加密算法要求
十六进制,必须以0x开头,后面跟对应密钥的十六进制内容
文件路径,将密钥保存到一个文件中,然后将文件绝对路径配置到这里,并确保长安链进程用户具有读写该文件的权限。 以下配置示例:
- storage:
- encryptor: aes # sm4/aes
- encrypt_key: "0x48656c6c6f20436861696e4d616b6572" #16 bytes key
- storage:
- encryptor: sm4 # sm4/aes
- encrypt_key: "/usr/key/my.key" #this file content is a 16 bytes key
完成TED的配置后,请确保当前节点没有任何数据,如果之前已经有数据,需要完全删除。节点启动后将会从创世区块开始基于TDE的密钥对每个区块每个交易每个世界状态Value进行统一的加密存储。 在encrypt_key上使用文件路径配置密钥的情况下,长安链在启动时将读取文件内容作为密钥,同时将文件内容清空,防止硬盘数据被盗时密钥也同时被盗。所以如果下次要重新启动长安链进程,必须重新在对应的密钥文件中写入密钥才能正常启动。
通过入口可点击到具体数据库的实现类,如leveldb的实现\store-leveldb\v2@v2.2.1\leveldb_handle.go核心代码如下:
- // Get returns the value for the given key, or returns nil if none exists
- func (h *LevelDBHandle) Get(key []byte) ([]byte, error) {
- value, err := h.db.Get(key, nil)
- if err == leveldb.ErrNotFound {
- value = nil
- err = nil
- }
- if err != nil {
- h.logger.Errorf("getting leveldbprovider key [%s], err:%s", key, err.Error())
- return nil, errors.Wrapf(err, "error getting leveldbprovider key [%s]", key)
- }
- if h.encryptor != nil && len(value) > 0 {
- return h.encryptor.Decrypt(value)
- }
- return value, nil
- }
-
- // Put saves the key-values
- func (h *LevelDBHandle) Put(key []byte, value []byte) error {
- if value == nil {
- h.logger.Warn("writing leveldbprovider key [%s] with nil value", key)
- return errors.New("error writing leveldbprovider with nil value")
- }
-
- if h.encryptor != nil && len(value) > 0 {
- var err error
- value, err = h.encryptor.Encrypt(value)
- if err != nil {
- return err
- }
- }
- err := h.db.Put(key, value, &opt.WriteOptions{Sync: true})
- if err != nil {
- h.logger.Errorf("writing leveldbprovider key [%s]", key)
- return errors.Wrapf(err, "error writing leveldbprovider key [%s]", key)
- }
- return err
- }
SM4算法DEMO及使用示例程序源码,可在此路径下载:
https://download.csdn.net/download/h363659487/86338711
运行示例可用于直接通过DB解密出上链数据原文。