当前位置:网站首页>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
边栏推荐
- How to adjust the color of the computer screen and how to change the color of the computer screen
- Automatique, intelligent, visuel! Forte conviction des huit conceptions derrière la solution sslo
- 广东用电量大跌,说明高新技术产业替代高能耗产业已取得初步成果
- ATSS:自动选择样本,消除Anchor based和Anchor free物体检测方法之间的差别
- Problems encountered in IM instant messaging development to maintain heartbeat
- ThinkPHP kernel work order system source code commercial open source version multi user + multi customer service + SMS + email notification
- 芯片供应转向过剩,中国芯片日产增加至10亿,国外芯片将更难受
- Pico,是要拯救还是带偏消费级VR?
- [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
- 圈铁发音,动感与无噪强强出彩,魔浪HIFIair蓝牙耳机测评
猜你喜欢
Huawei issued hcsp-solution-5g security talent certification to help build 5g security talent ecosystem
How long will it take to achieve digital immortality? Metacosmic holographic human avatar 8i
Automatic, intelligent and visual! Deeply convinced of the eight designs behind sslo scheme
韩国AI团队抄袭震动学界!1个导师带51个学生,还是抄袭惯犯
Crypto Daily:孙宇晨在MC12上倡议用数字化技术解决全球问题
The picgo shortcut is amazing. This person thinks exactly the same as me
2023 spring recruitment Internship - personal interview process and face-to-face experience sharing
picgo快捷键 绝了这人和我的想法 一模一样
Thinkphp内核工单系统源码商业开源版 多用户+多客服+短信+邮件通知
There is a difference between u-standard contract and currency standard contract. Will u-standard contract explode
随机推荐
Crypto Daily: Sun Yuchen proposed to solve global problems with digital technology on MC12
【开源数据】基于虚拟现实场景的跨模态(磁共振、脑磁图、眼动)人类空间记忆研究开源数据集
制造业数字化转型究竟是什么
SQLServer查询: a.id与b.id相同时,a.id对应的a.p在b.id对应的b.p里找不到的话,就显示出这个a.id和a.p
【LeetCode】43. String multiplication
The picgo shortcut is amazing. This person thinks exactly the same as me
ABAP call restful API
超视频时代,什么样的技术会成为底座?
Go language learning notes - Gorm use - table addition, deletion, modification and query | web framework gin (VIII)
大龄测试/开发程序员该何去何从?是否会被时代抛弃?
Action after deleting laravel's model
韩国AI团队抄袭震动学界!1个导师带51个学生,还是抄袭惯犯
Share the daily work and welfare of DJI (Shenzhen headquarters) in Dajiang
接口测试框架中的鉴权处理
Five years after graduation, I became a test development engineer with an annual salary of 30w+
Win11如何设置用户权限?Win11设置用户权限的方法
When ABAP screen switching, refresh the previous screen
The latest NLP game practice summary!
Please, stop painting star! This has nothing to do with patriotism!
程序员职业生涯真的很短吗?