长安链透明数据加密(TDE)介绍及SM4算法源码梳理

概述

透明数据加密(Transparent Data Encryption (简称TDE))是指可以在文件层对数据和文件进行实时加密和解密,落盘的文件是加密后的内容,而对于上层应用系统和开发人员而言,加解密过程是无感知的,写入和读取的内容是明文内容,所以叫做透明数据加密。长安链密码模块同时提供了软件实现和硬件集成,使用以下步骤即可完成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上使用文件路径配置密钥的情况下,长安链在启动时将读取文件内容作为密钥,同时将文件内容清空,防止硬盘数据被盗时密钥也同时被盗。所以如果下次要重新启动长安链进程,必须重新在对应的密钥文件中写入密钥才能正常启动。

源码分析

入口源码路径:

chainmaker / store · ChainMaker

通过入口可点击到具体数据库的实现类,如leveldb的实现\store-leveldb\[email protected]\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解密出上链数据原文。

猜你喜欢

转载自blog.csdn.net/h363659487/article/details/126181206