关于go:golang密文存储

38次阅读

共计 1781 个字符,预计需要花费 5 分钟才能阅读完成。

需要

加密存储用户数据,实现即便数据库泄露,也能保障用户数据的平安。

思路

  • 应用 AES 解决 一般数据
  • 应用 Argon2 解决 非凡数据

    以加密后 是否须要解密 为规范辨别:
    加密后须要解密的,为一般数据(手机号 邮箱 )。
    反之,为非凡数据(登录明码)。

实现

AES 解决一般数据

AES,Advanced Encryption Standard,高级加密规范。

// AES key,16、24 或者 32 位,顺次对应 AES-128、AES-192 和 AES-256。const key = "1234567887654321"

// AES 加密
func AESEncrypt(plainText []byte) ([]byte, error) {block, err := aes.NewCipher([]byte(key)) // 应用 AES key 生成 cipher.Block 接口
    if err != nil {return nil, err}
    plainText = pkcs5Append(plainText, block.BlockSize())                         // 填充最初一个分组的数据
    blockMode := cipher.NewCBCEncrypter(block, ([]byte(key))[:block.BlockSize()]) // 生成 BlockMode 接口
    cipherText := plainText
    blockMode.CryptBlocks(cipherText, plainText) // 加密
    return cipherText, nil
}

// AES 解密
func AESDecrypt(cipherText []byte) ([]byte, error) {block, err := aes.NewCipher([]byte(key)) // 应用 AES key 生成 cipher.Block 接口
    if err != nil {return nil, err}
    blockMode := cipher.NewCBCEncrypter(block, ([]byte(key))[:block.BlockSize()]) // 生成 BlockMode 接口
    plainText := cipherText
    blockMode.CryptBlocks(plainText, cipherText) // 解密
    plainText = pkcs5Trim(plainText)
    return plainText, nil
}

// 应用 PKCS#5 算法填充最初一个分组的数据
func pkcs5Append(ciphertext []byte, blockSize int) []byte {padding := blockSize - (len(ciphertext) % blockSize)    // 计算最初一个分组缺多少个字节
    padText := bytes.Repeat([]byte{byte(padding)}, padding) // 创立一个大小为 padding 的切片, 每个字节的值为 padding
    newText := append(ciphertext, padText...)               // 将 padText 增加到原始数据的后边, 将最初一个分组短少的字节数补齐
    return newText
}

// 删除填充的数据
func pkcs5Trim(origData []byte) []byte {length := len(origData)             // 计算数据的总长度
    number := int(origData[length-1])   // 依据填充的字节值得到填充的次数
    return origData[:(length - number)] // 将尾部填充的 number 个字节去掉
}

Argon2 解决非凡数据

Argon2,明码散列比赛 冠军 算法,是比 bcryptscrypt 更牢靠的明码散列算法。

go get -u golang.org/x/crypto/argon2
// 定义盐
salt := "some salt"

// 基于 Argon2id 生成明码的散列值
key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32)

// 将 key 编码为 base64 字符串
data := base64.StdEncoding.EncodeToString(key)

Password Hashing Competition
phc-winner-argon2
golang/crypto
罕用明码技术 | 爱编程的大丙

正文完
 0