需求

加密存储用户数据,实现即使数据库泄露,也能保证用户数据的安全。

思路

  • 使用AES处理普通数据
  • 使用Argon2处理特殊数据

    以加密后是否需要解密为标准区分:
    加密后需要解密的,为普通数据(手机号邮箱)。
    反之,为特殊数据(登录密码)。

实现

AES处理普通数据

AES,Advanced Encryption Standard,高级加密标准。

加密

func AESEncrypt(plainText []byte) ([]byte, error) {
    // 判空
    if len(plainText) == 0 {
        return plainText, nil
    }

    // 生成数据块接口
    block, err := aes.NewCipher([]byte(key))
    if err != nil {
        return nil, err
    }

    // AES以128比特(16字节)为单位进行分组加密
    // 若最后的分组不足16字节,需补足至16字节
    if len(plainText)%block.BlockSize() > 0 {
        // 计算缺口(1-15)
        lack := block.BlockSize() - len(plainText)%block.BlockSize()
        // 生成填充的bytes数组
        padding := bytes.Repeat([]byte{byte(lack)}, lack)
        // 填充
        plainText = append(plainText, padding...)
    }

    // 生成CBC模式的加密接口
    encrypter := cipher.NewCBCEncrypter(
        block, ([]byte(key))[:block.BlockSize()],
    )

    // 加密
    cipherText := make([]byte, len(plainText))
    encrypter.CryptBlocks(cipherText, plainText)
    return cipherText, nil
}

解密

func AESDecrypt(cipherText []byte) ([]byte, error) {
    // 判空
    if len(cipherText) == 0 {
        return cipherText, nil
    }

    // 生成数据块接口
    block, err := aes.NewCipher([]byte(key))
    if err != nil {
        return nil, err
    }

    // 生成CBC模式的解密接口
    decrypter := cipher.NewCBCDecrypter(
        block, ([]byte(key))[:block.BlockSize()],
    )

    // 解密
    plainText := make([]byte, len(cipherText))
    decrypter.CryptBlocks(plainText, cipherText)

    // 剔除加密时填充的部分
    if plainText[len(plainText)-1] < 16 {
        plainText = plainText[:(len(plainText) - int(plainText[len(plainText)-1]))]
    }
    return plainText, nil
}

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
常用密码技术 | 爱编程的大丙

从君华
139 声望7 粉丝

万物之中,简洁最美。