分享

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

 小生凡一 2022-10-22 发布于福建

写在前面

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

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

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

github地址

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

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多