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

写在前面

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

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

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

secret 包新特性 | 多位密钥支持 & 多种模式选择_第1张图片

这一次重点介绍一下新增的一些新特性,主要是在 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. 性能测试

你可能感兴趣的:(遇见Golang,拥抱未来,加密,aes,des,golang,encrypt)