Rumah >pembangunan bahagian belakang >Golang >Gunakan cipher.AEAD.Seal() untuk melihat penggunaan memori
Saya menggunakan pelaksanaan ChaCha20-Poly1305 Go untuk menyulitkan data, tetapi apabila saya menyulitkan beberapa fail besar, penggunaan memori adalah lebih tinggi daripada yang saya jangkakan. Setakat yang saya tahu, pelaksanaan sifir AEAD Go bermakna kita perlu menyimpan keseluruhan data dalam ingatan untuk mencipta cincang, tetapi penggunaan memori adalah dua kali ganda saiz plaintext.
Atur cara kecil berikut yang cuba menyulitkan 4 GiB data menyerlahkan perkara ini (dalam program dunia sebenar, key
和 nonce
tidak sepatutnya kosong):
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) }
Menurut kod sumber crypto/cipher/gcm.go
(digunakan oleh kedua-dua AES-GCM dan ChaCha20-Poly1305) terdapat ulasan berikut:
// 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
Ini bermakna saya sepatutnya boleh menggunakan semula memori, saya telah cuba melakukan ini, tetapi ia tidak memberi kesan pada jumlah memori yang digunakan oleh aplikasi saya - selepas memanggil Seal()
kami sentiasa menggunakan 8 GiB memori Can 4 GiB data disulitkan?
[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
Jika ia menggunakan semula ingatan (seperti yang tersirat), maka saya tidak sepatutnya menjangkakan sebarang peningkatan yang ketara selain daripada cipher yang agak kecil yang ditambahkan oleh sifir AEAD pada teks sifir?
Anda terlupa untuk mengambil kira token pengesahan yang dilampirkan pada teks sifir. Jika anda memberi ruang untuknya dalam peruntukan awal, tiada peruntukan lanjut diperlukan:
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
Atas ialah kandungan terperinci Gunakan cipher.AEAD.Seal() untuk melihat penggunaan memori. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!