Keputusan Berbeza dalam Go dan Pycrypto Apabila Menggunakan AES-CFB
Isu yang dibentangkan di sini melibatkan penyulitan data menggunakan AES-CFB dengan Go dan Pycrypto , menghasilkan teks sifir yang berbeza. Sampel Python dan Go yang disediakan menggunakan kunci, IV dan teks biasa yang sama namun menghasilkan data disulitkan yang sangat berbeza:
Python: dbf6b1877ba903330cb9cf0c4f530d40bf77fe2bf505820e993741c7f698ad6b
Pergi: db70cd9e6904359cb848410bfa38d7d0a47b594f7eff72d547d3772c9d4f5dbe
Setiap bahasa boleh menyahsulit teks sifirnya sendiri tetapi gagal menyahsulit output bahasa lain, menghalang kebolehoperasian.
Resolusi
Perbezaan berpunca daripada saiz segmen bit berbeza yang digunakan untuk mod CFB oleh Python dan Go. Python menggunakan CFB8, di mana data diproses dalam segmen 8-bit, manakala pelaksanaan lalai Go memproses data dalam blok 128-bit.
Untuk menyelesaikan isu dan memastikan Go boleh menyahsulit teks sifir yang disulitkan menggunakan tetapan AES-CFB Pycrypto, seseorang mesti mengubah suai CFBEncrypter / CFBDecrypter Go agar serasi dengan segmen 8-bit. Sampel Go yang disediakan bergantung pada kod dalam fungsi ini untuk melaksanakan penyulitan CFB.
Penyesuaian ini melibatkan:
Melaksanakan fungsi NewCFBDecrypter tersuai yang menetapkan saiz segmen kepada 8 :
func NewCFBDecrypter(block cipher.Block, iv []byte) cipher.Stream { if len(block.BlockSize()) != aes.BlockSize { panic("cipher: NewCFBDecrypter: invalid block size") } cfb := cfbDecrypter{ blockSize: block.BlockSize(), iv: iv, segmentSize: 8, enc: block, ofb: copyBlock(block), } resetOfb(&cfb) return &cfb }
Mengubah suai Fungsi XORKeyStream untuk memproses data dalam ketulan 8-bit dan bukannya blok 128-bit:
func (x *cfbDecrypter) XORKeyStream(dst, src []byte) { dst = dst[:len(src)] switch { case len(src) == 0: return case len(src) < x.segmentSize: x.segBuf[0:len(src)] = src x.segPos = len(src) default: segmentSize := x.segmentSize for i := 0; i < len(src)-segmentSize+1; i += segmentSize { j := i + segmentSize xorBytes(dst[i:j], src[i:j], x.iv[x.segI:]) x.encryptLogical(x.iv[x.segI:], x.segBuf[:segmentSize]) copy(x.iv[x.segI:], dst[i:j]) x.segI += segmentSize if x.segI >= x.blockSize { x.segI = 0 } } n := len(src) - len(src)%x.segmentSize x.segBuf[0:len(src[n:])] = src[n:] x.segPos = len(src[n:]) } }
Dengan perubahan ini, sampel Go harus menghasilkan teks sifir yang sama seperti pelaksanaan Python:
payload, err1 := hex.DecodeString("abababababababababababababababababababababababababababababababab") password, err2 := hex.DecodeString("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF") iv, err3 := hex.DecodeString("00000000000000000000000000000000") if err1 != nil { fmt.Printf("error 1: %v", err1) return } if err2 != nil { fmt.Printf("error 2: %v", err2) return } if err3 != nil { fmt.Printf("error 3: %v", err3) return } aesBlock, err4 := aes.NewCipher(password) iv = iv[0:aes.BlockSize] // Trim the IV if it's longer than the AES block size fmt.Printf("IV length:%v\n", len(iv)) fmt.Printf("password length:%v\n", len(password)) if err4 != nil { fmt.Printf("error 4: %v", err4) return } cfbDecrypter := cipher.NewCFBDecrypter(aesBlock, iv) cfbDecrypter.XORKeyStream(payload, payload) fmt.Printf("%v\n", hex.EncodeToString(payload)) // dbf6b1877ba903330cb9cf0c4f530d40bf77fe2bf505820e993741c7f698ad6b
Atas ialah kandungan terperinci Mengapakah Go dan Pycrypto menghasilkan teks sifir yang berbeza apabila menggunakan AES-CFB, dan bagaimanakah perkara ini boleh diselesaikan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!