J'utilise l'implémentation ChaCha20-Poly1305 de Go pour crypter des données, mais lorsque je crypte certains fichiers volumineux, l'utilisation de la mémoire est plus élevée que prévu. Pour autant que je sache, l'implémentation du chiffrement AEAD de Go signifie que nous devons conserver l'intégralité des données en mémoire pour créer le hachage, mais l'utilisation de la mémoire est deux fois supérieure à la taille du texte en clair.
Le petit programme suivant essayant de chiffrer 4 Gio de données le met en évidence (dans un programme réel, key
和 nonce
ne devrait pas être vide) :
package main import ( "os" "fmt" "runtime" "golang.org/x/crypto/chacha20poly1305" ) func main() { showMemUsage("START") plaintext := make([]byte, 4 * 1024 * 1024 * 1024) // 4 GiB showMemUsage("STAGE 1") key := make([]byte, chacha20poly1305.KeySize) if cipher, err := chacha20poly1305.New(key); err == nil { showMemUsage("STAGE 2") nonce := make([]byte, chacha20poly1305.NonceSize) cipher.Seal(plaintext[:0], nonce, plaintext, nil) } showMemUsage("END") } func showMemUsage(tag string) { var m runtime.MemStats runtime.ReadMemStats(&m) fmt.Fprintf(os.Stdout, "[%s] Alloc = %v MiB, TotalAlloc = %v MiB\n", tag, m.Alloc / 1024 / 1024, m.TotalAlloc / 1024 / 1024) }
Selon le code source de crypto/cipher/gcm.go
(utilisé à la fois par AES-GCM et ChaCha20-Poly1305), il y a les commentaires suivants :
// To reuse plaintext's storage for the encrypted output, use plaintext[:0] // as dst. Otherwise, the remaining capacity of dst must not overlap plaintext. Seal(dst, nonce, plaintext, additionalData []byte) []byte
Cela signifie que je devrais pouvoir réutiliser la mémoire, j'ai essayé de le faire, mais cela n'a aucun effet sur la quantité de mémoire utilisée par mon application - après avoir appelé Seal()
nous finissons toujours par utiliser 8 Go de mémoire Can 4 Les Gio de données doivent-ils être chiffrés ?
[START] Alloc = 0 MiB, TotalAlloc = 0 MiB [STAGE 1] Alloc = 4096 MiB, TotalAlloc = 4096 MiB [STAGE 2] Alloc = 4096 MiB, TotalAlloc = 4096 MiB [END] Alloc = 8192 MiB, TotalAlloc = 8192 MiB
S'il réutilise la mémoire (comme indiqué), alors je ne devrais pas m'attendre à une augmentation significative autre que le hachage relativement petit que le chiffrement AEAD ajoute au texte chiffré ?
Vous avez oublié de prendre en compte le jeton d'authentification ajouté au texte chiffré. Si vous lui faites de la place dans la dotation initiale, aucune dotation supplémentaire n'est nécessaire :
package main import ( "fmt" "os" "runtime" "golang.org/x/crypto/chacha20poly1305" ) func main() { showMemUsage("START") plaintext := make([]byte, 4<<30, 4<<30+chacha20poly1305.Overhead) showMemUsage("STAGE 1") key := make([]byte, chacha20poly1305.KeySize) if cipher, err := chacha20poly1305.New(key); err == nil { showMemUsage("STAGE 2") nonce := make([]byte, chacha20poly1305.NonceSize) cipher.Seal(plaintext[:0], nonce, plaintext, nil) } showMemUsage("END") } func showMemUsage(tag string) { var m runtime.MemStats runtime.ReadMemStats(&m) fmt.Fprintf(os.Stdout, "[%s] Alloc = %v MiB, TotalAlloc = %v MiB\n", tag, m.Alloc>>20, m.TotalAlloc>>20) } // Output: // [START] Alloc = 0 MiB, TotalAlloc = 0 MiB // [STAGE 1] Alloc = 4096 MiB, TotalAlloc = 4096 MiB // [STAGE 2] Alloc = 4096 MiB, TotalAlloc = 4096 MiB // [END] Alloc = 4096 MiB, TotalAlloc = 4096 MiB
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!