secret 包新特性 | 多位密钥支持 & 多种模式选择

Posted 小生凡一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了secret 包新特性 | 多位密钥支持 & 多种模式选择相关的知识,希望对你有一定的参考价值。

写在前面

这是我封装的一个加密库,secret包,上层抽离接口,让我们的更容易对敏感数据进行脱敏处理

github地址:https://github.com/CocaineCong/secret

这里就不再过多赘述 AES/DES/3DES/RSA 等的加密算法

这一次重点介绍一下新增的一些新特性,主要是在 AES 加密这一块。

AES

1. 密钥长度

我们新增了对密钥程度的加密的选择。可以选择 128、192、256 三种长度的密钥进行加密,更加灵活方便。

type AesKeyType uint64 
const (
	AesEncrypt128 AesKeyType = 128
	AesEncrypt192 AesKeyType = 192
	AesEncrypt256 AesKeyType = 256
)

2. 加密模式

之前版本仅支持 CBC模式 的加密,这次我们扩展了 CFB / CTR / OFB 三种模式。

让我们加密模式的选择更多样化。

// AES 加密模式
const (
	AesModeTypeCBC AesModeType = "CBC" // Cipher Block Chaining
	AesModeTypeCFB AesModeType = "CFB" // Cipher FeedBack
	AesModeTypeCTR AesModeType = "CTR" // Counter
	AesModeTypeOFB AesModeType = "OFB" // Output FeedBack
)

同样的,为了兼容更多的模式,我们扩展了AES对象。

type AesEncrypt struct 
	SpecialSign string // 加解密都会基于这一串字符,如果没有会基于 AesBaseSpecialSign.
	Key         string // 密钥,建议是 5-8位的密钥

	IV string // 初始向量 16 字节

	AesModeType AesModeType // 加密类型

	AesKeyType   AesKeyType // 加密类型
	AesKey       []byte     // AES 密钥
	AesKeyLength int        // 加密长度

	PlainTextLength int // 加密对象的长度

虽然字段增加多了,但是很多都是封装实现的,不需要用户将全部的参数都输入来进行构建

用户只需要选择传入必要的参数即可,非常方便简洁,甚至不需要输入iv

举个例子:

specialSign := "a1231243124124314vczxfda124sd"
key := "458796" // key 密钥
aesEncrypt, _ := NewAesEncrypt(specialSign, key, "", AesEncrypt128, AesModeTypeCTR)

我们只是在原先的基础上,增加了iv初始向量以及选择加密的长度。

并且与之前一样的加解密操作。

str := aesEncrypt.SecretEncrypt("this is a secret")
fmt.Println(str)
ans := aesEncrypt.SecretDecrypt(str)
fmt.Println(ans)

以上的新加的功能都是基于AES的,目前DES是不太考虑加了,可能后续会新增3DES的加密mode。

这里提一下关于两个新加入的加密 mode CTR AND OFB

  • 加密
    这里我们的CTR和OFB加密和解密都是可以直接一个New就完事了,非常的简洁和方便,与 CBC/CFB 不同,CBC/CFB 则需要区分 Encrypt 和 Decrypt。
// aesEncrypter CTR OR OFB 模式的加密
func (a *AesEncrypt) aesEncrypter(encodeStr string, block cipher.Block, mode AesModeType) (string, error) 
	cipherText := make([]byte, a.PlainTextLength)
	m := cipher.NewCTR(block, []byte(a.IV))
	if mode == AesModeTypeCFB 
		m = cipher.NewOFB(block, []byte(a.IV))
	
	copy(cipherText, encodeStr)
	m.XORKeyStream(cipherText, cipherText)
	return hex.EncodeToString(cipherText), nil

  • 解密
// aesDecrypter CTR OR OFB 模式的加密
func (a *AesEncrypt) aesDecrypter(decodeBytes []byte, block cipher.Block, mode AesModeType) (string, error) 
	m := cipher.NewCTR(block, []byte(a.IV))
	if mode == AesModeTypeCFB 
		m = cipher.NewOFB(block, []byte(a.IV))
	
	plainTextCopy := make([]byte, a.PlainTextLength)
	copy(plainTextCopy, decodeBytes)
	m.XORKeyStream(plainTextCopy, plainTextCopy)
	return string(plainTextCopy), nil

3. 拼接选择

这一次我们抽离对 specialSign 的填充操作。目前还是裁剪,后面打算换成hash,并且将string 由 编码的形式呈现

如果这个 specialSign 加上 key

  • 不足对应的加密密钥的长度,那么我们会用 BaseSpecialSign 对specialSign 进行 填充。
  • 如果大于对应的加密密钥的长度,我们会根据奇偶来判断,是取前缀还是后缀。
func formatSpecialSign(specialSign, key string, keyLength int) string 
	specialSignLength := len(specialSign)
	if specialSignLength+len(key) < keyLength 
		log.Printf("【WARN】 the length of specialSign and key less %v ", keyLength)
		if specialSignLength%2 == 0 
			specialSign += BaseSpecialSign[:keyLength-len(specialSign)]
		 else 
			specialSign += BaseSpecialSign[BaseSpecialSignLength-keyLength:]
		
	
	if specialSignLength > keyLength 
		if specialSignLength%2 == 0 
			specialSign = specialSign[:keyLength+1]
		 else 
			specialSign = specialSign[len(specialSign)-keyLength:]
		
	
	return specialSign

多位密钥支持 & 多种模式选择

以上就是这次的新改型。

下一个版本会解决的问题:

  1. hash 填充代替
  2. 3DES 支持多模式
  3. 性能测试

以上是关于secret 包新特性 | 多位密钥支持 & 多种模式选择的主要内容,如果未能解决你的问题,请参考以下文章

我可以调整移动的向量的大小吗?

Dapr + .NET Core实战Secrets

使用 Azure.Security.KeyVault.Secrets 的网络核心密钥保管库配置

Dapr + .NET 实战Secrets

K8S集群中部署Secret保存密钥(14)

无法使用 Secrets Manager 密钥注册 AWS Batch 作业定义