AES-CFB を使用すると Go と Pycrypto で異なる結果が発生する
ここで紹介する問題には、Go と Pycrypto で AES-CFB を使用したデータの暗号化が含まれます、結果として異なる暗号文が生成されます。提供されている Python と Go のサンプルは、同一のキー、IV、平文を使用していますが、非常に異なる暗号化データを生成します。
Python: dbf6b1877ba903330cb9cf0c4f530d40bf77fe2bf505820e993741c7f698ad6b
Go: db70cd9e6904359cb848410bfa38d7d0a47b594f7eff72d547d3772c9d4f5dbe
各言語は独自の暗号文を復号化できますが、他の言語の出力を復号化できないため、暗号化が妨げられます。
解像度
この不一致は、Python と Go で CFB モードに使用されるビット セグメント サイズの違いに起因します。 Python は CFB8 を利用し、データは 8 ビット セグメントで処理されますが、Go のデフォルト実装ではデータが 128 ビット ブロックで処理されます。
問題を解決し、Pycrypto の AES-CFB 設定を使用して暗号化された暗号文を Go が復号できるようにするには、次のようにします。 8 ビット セグメントと互換性があるように Go の CFBEncrypter / CFBDecrypter を変更する必要があります。提供されている Go サンプルは、これらの関数内のコードに依存して CFB 暗号化を実行します。
このカスタマイズには以下が含まれます:
セグメント サイズを 8 に設定するカスタム NewCFBDecrypter 関数の実装:
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 }
128 ビット ブロックではなく 8 ビット チャンクでデータを処理する XORKeyStream 関数:
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:]) } }
これらの変更により、Go サンプルは 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
以上がAES-CFB を使用すると Go と Pycrypto が異なる暗号文を生成するのはなぜですか? これはどのように解決できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。