Ich verwende die ChaCha20-Poly1305-Implementierung von Go, um Daten zu verschlüsseln, aber wenn ich einige große Dateien verschlüssele, ist die Speichernutzung höher als erwartet. Soweit ich weiß, bedeutet die AEAD-Verschlüsselungsimplementierung von Go, dass wir die gesamten Daten im Speicher behalten müssen, um den Hash zu erstellen, aber die Speichernutzung ist doppelt so groß wie die Klartextgröße.
Das folgende kleine Programm, das versucht, 4 GiB an Daten zu verschlüsseln, verdeutlicht dies (in einem realen Programm sollte key
和 nonce
nicht leer sein):
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) }
Laut dem Quellcode von crypto/cipher/gcm.go
(sowohl von AES-GCM als auch von ChaCha20-Poly1305 verwendet) gibt es die folgenden Kommentare:
// 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
Das bedeutet, dass ich in der Lage sein sollte, den Speicher wiederzuverwenden. Ich habe es versucht, aber es hat keine Auswirkungen auf die von meiner Anwendung verwendete Speichermenge – nach dem Aufruf Seal()
verwenden wir am Ende immer 8 GiB Speicher Can 4 GiB an Daten verschlüsselt werden?
[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
Wenn der Speicher wiederverwendet wird (wie angedeutet), sollte ich dann keine signifikante Steigerung außer dem relativ kleinen Hash erwarten, den die AEAD-Verschlüsselung dem Chiffretext hinzufügt?
Sie haben vergessen, das an den Chiffretext angehängte Authentifizierungstoken zu berücksichtigen. Wenn Sie in der Erstzuteilung Platz dafür schaffen, ist keine weitere Zuteilung notwendig:
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
Das obige ist der detaillierte Inhalt vonVerwenden Sie cipher.AEAD.Seal(), um die Speichernutzung anzuzeigen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!