当前位置:网站首页>Go 语言怎么使用对称加密?
Go 语言怎么使用对称加密?
2022-07-01 16:11:00 【frank.】
大家好,我是 frank。
01
介绍
在项目开发中,我们经常会遇到需要使用对称密钥加密的场景,比如客户端调用接口时,参数包含手机号、身份证号或银行卡号等。
对称密钥加密是一种加密方式,其中只有一个密钥用于加密和解密数据。通过对称加密进行通信的实体必须共享该密钥,以便可以在解密过程中使用它。这种加密方法与非对称加密不同,非对称加密使用一对密钥(一个公钥和一个私钥)来加密和解密数据。
02
AES 算法
常见的对称密钥加密算法有 AES (Advanced Encryption Standard),DES (Data Encryption Standard) 等,它们都属于分组密码。
因为基于目前计算机的处理能力,可以很快破解 DES 算法,所以 DES 目前已经很少被使用。
AES 是目前最常用的对称密钥加密算法,最初称为 Rijndael。AES 密码每个分组大小是 128 bits,但是它具有三种密钥长度,分别是 AES-128、AES-192 和 AES-256。需要注意的是,在 Golang 标准库提供的接口中,仅支持 AES-128(16 byte),实际上 AES-128 的加密强度已经足够安全。
本文我们主要介绍 Golang 中怎么使用 AES 算法的对称密钥加密。
03
实践
AES 算法的分组模式包含 ECB、CBC、CFB、OFB 和 CTR,其中 ECB 和 CBC 使用比较多,虽然 ECB 比 CBC 简单,效率高,但是它的密文有规律,比较容易破解,所以,更推荐大家使用 CBC,本文我们主要介绍使用最多的 CBC 分组模式。
需要注意的是,ECB 和 CBC 分组模式的最后一个分组,需要填充满 16 byte,关于填充模式,限于篇幅,本文不展开介绍,但会提供填充数据和取消填充数据的代码。
Golang 实现 AES 对称加密算法主要分为以下几个步骤:
加密步骤:
- 创建一个新的加密块。
- 获取加密块的大小。
- 填充数据。
- 初始化向量。
- 指定加密块的分组模式。
- 进行加密多个块。
示例代码:
func AESCbcEncrypt(secretKey, src string) string {
key := []byte(secretKey)
if len(key) > 16 {
key = key[:16]
}
plaintext := []byte(src)
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
blockSize := block.BlockSize()
plaintext = Padding(plaintext, blockSize)
if len(plaintext)%aes.BlockSize != 0 {
panic("plaintext is not a multiple of the block size")
}
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
return base64.StdEncoding.EncodeToString(ciphertext)
}
解密步骤:
- 创建一个新的加密块。
- 初始化向量。
- 指定解密块的分组模式。
- 进行解密多个块。
- 取消填充数据。
示例代码:
func AESCbcDecrypt(secretKey, src string) string {
key := []byte(secretKey)
ciphertext, _ := base64.StdEncoding.DecodeString(src)
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
if len(ciphertext) < aes.BlockSize {
panic("ciphertext too short")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
if len(ciphertext)%aes.BlockSize != 0 {
panic("ciphertext is not a multiple of the block size")
}
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(ciphertext, ciphertext)
ciphertext = UnPadding(ciphertext)
return string(ciphertext)
}
填充示例代码:
func Padding(plainText []byte, blockSize int) []byte {
padding := blockSize - len(plainText)%blockSize
char := []byte{byte(padding)}
newPlain := bytes.Repeat(char, padding)
return append(plainText, newPlain...)
}
取消填充示例代码:
func UnPadding(plainText []byte) []byte {
length := len(plainText)
lastChar := plainText[length-1]
padding := int(lastChar)
return plainText[:length-padding]
}
需要注意的是,初始化向量(IV)是随机的,细心的读者朋友们可能已经发现,使用随机 IV ,同一份明文,每次加密得到的密文也都不同。但是,加密和解密使用的 IV 必须相同。
04
总结
本文我们介绍了对称密钥加密的概念,并简单介绍了 AES 算法,最终我们还提供了 Golang 怎么使用 AES 算法的 CBC 分组模式实现对称密钥加密的示例代码,感兴趣的读者朋友,可以自行编写其它分组模式的代码。
本文重点是介绍怎么使用 Go 语言实现对称密钥加密,代码占用篇幅比较多,关于 AES 算法的分组模式和填充模式的详细介绍,感兴趣的读者朋友们可以阅读参考资料给出的链接地址。
参考资料:
- https://en.wikipedia.org/wiki/Symmetric-key_algorithm
- https://pkg.go.dev/crypto/[email protected]#NewCipher
- https://pkg.go.dev/crypto/cipher#NewCBCEncrypter
- https://pkg.go.dev/crypto/cipher#NewCBCDecrypter
- https://datatracker.ietf.org/doc/html/rfc5246#section-6.2.3.2
- https://en.wikipedia.org/wiki/Padding_(cryptography)
- https://www.cryptomathic.com/news-events/blog/the-use-of-encryption-modes-with-symmetric-block-ciphers
边栏推荐
- 分享在大疆DJI(深圳总部)工作的日常和福利
- 基于PHP的轻量企业销售管理系统
- HR interview: the most common interview questions and technical answers
- Principle of motion capture system
- [nodemon] app crashed - waiting for file changes before starting...解决方法
- 【观察】数字化时代的咨询往何处走?软通咨询的思与行
- Please, stop painting star! This has nothing to do with patriotism!
- 【Hot100】19. 删除链表的倒数第 N 个结点
- Pico, can we save consumer VR?
- In the era of super video, what kind of technology will become the base?
猜你喜欢
StoneDB 为国产数据库添砖加瓦,基于 MySQL 的一体化实时 HTAP 数据库正式开源!
Problems encountered in IM instant messaging development to maintain heartbeat
#夏日挑战赛# HarmonyOS canvas实现时钟
[SQL statement] Why do you select two Shanghai and query different counts here? I want it to become a Shanghai, and count only displays a sum
Hardware development notes (9): basic process of hardware development, making a USB to RS232 module (8): create asm1117-3.3v package library and associate principle graphic devices
Research on multi model architecture of ads computing power chip
最新NLP赛事实践总结!
Zero copy technology of MySQL
【IDM】IDM下载器安装
How long will it take to achieve digital immortality? Metacosmic holographic human avatar 8i
随机推荐
The picgo shortcut is amazing. This person thinks exactly the same as me
表格存储中tablestore 目前支持mysql哪些函数呢?
Advanced cross platform application development (24): uni app realizes file download and saving
Summer Challenge harmonyos canvas realize clock
[daily news]what happened to the corresponding author of latex
[每日一氵]Latex 的通讯作者怎么搞
ATSs: automatically select samples to eliminate the difference between anchor based and anchor free object detection methods
2022 Moonriver global hacker song winning project list
【Hot100】19. 删除链表的倒数第 N 个结点
Uncover the "intelligence tax" of mousse: spend 4billion on marketing, and only 7 invention patents
How does win11 set user permissions? Win11 method of setting user permissions
2022 Moonriver全球黑客松优胜项目名单
MySQL的零拷贝技术
Im instant messaging develops a message delivery scheme for 10000 people
IM即時通訊開發實現心跳保活遇到的問題
2023 spring recruitment Internship - personal interview process and face-to-face experience sharing
C#/VB. Net merge PDF document
Korean AI team plagiarizes shock academia! One tutor with 51 students, or plagiarism recidivist
Solution to the problem that the keypad light does not light up when starting up
电脑照片尺寸如何调整成自己想要的