Golang中x/crypto/chacha20poly1305是否线程安全?
Golang中x/crypto/chacha20poly1305是否线程安全?
关于 x/crypto 中实现 chacha20poly1305 AEAD 的包:golang.org/x/crypto/chacha20poly1305
查看代码,AEAD 结构体中唯一的字段是密钥,该字段在加密/解密过程中永远不会被更新。是否应该更新文档以表明该 Cipher 是线程安全的?或者为了向后兼容性,这样承诺是否过于绝对?
更多关于Golang中x/crypto/chacha20poly1305是否线程安全?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中x/crypto/chacha20poly1305是否线程安全?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
根据 golang.org/x/crypto/chacha20poly1305 包的实现,AEAD 结构体确实只包含密钥字段,且该字段在加密/解密过程中不会被修改。从代码层面看,该实现是线程安全的,因为:
AEAD结构体不包含任何可变状态(如计数器、随机数等),这些状态通过方法参数传递。- 加密(
Seal)和解密(Open)操作仅依赖于密钥和传入的参数,不修改内部状态。
示例代码:
package main
import (
"crypto/rand"
"fmt"
"golang.org/x/crypto/chacha20poly1305"
"sync"
)
func main() {
key := make([]byte, chacha20poly1305.KeySize)
if _, err := rand.Read(key); err != nil {
panic(err)
}
aead, err := chacha20poly1305.New(key)
if err != nil {
panic(err)
}
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
nonce := make([]byte, chacha20poly1305.NonceSize)
if _, err := rand.Read(nonce); err != nil {
panic(err)
}
plaintext := []byte(fmt.Sprintf("message %d", i))
ciphertext := aead.Seal(nil, nonce, plaintext, nil)
decrypted, err := aead.Open(nil, nonce, ciphertext, nil)
if err != nil {
panic(err)
}
fmt.Printf("Goroutine %d: %s\n", i, decrypted)
}(i)
}
wg.Wait()
}
该代码展示了多个 goroutine 并发使用同一个 AEAD 实例进行加密和解密操作,不会引发数据竞争。因此,从实现角度看,chacha20poly1305.AEAD 是线程安全的。但官方文档未明确声明这一点,可能是为了保持灵活性,避免未来实现变更时破坏兼容性。

