Différents résultats dans Go et Pycrypto lors de l'utilisation d'AES-CFB
Le problème présenté ici concerne le cryptage de données à l'aide d'AES-CFB avec Go et Pycrypto , ce qui donne lieu à des textes chiffrés différents. Les exemples Python et Go fournis utilisent des clés, des IV et des textes en clair identiques, mais produisent des données chiffrées très distinctes :
Python : dbf6b1877ba903330cb9cf0c4f530d40bf77fe2bf505820e993741c7f698ad6b
Go : db70cd9e6904359cb848410bfa38d7d0a47b594f7eff72d547d3772c9d4f5dbe
Chaque langue peut déchiffrer son propre texte chiffré mais ne parvient pas à déchiffrer la sortie de l'autre, ce qui gêne interopérabilité.
Résolution
La disparité provient des différentes tailles de segments de bits utilisées pour le mode CFB par Python et Go. Python utilise CFB8, où les données sont traitées par segments de 8 bits, tandis que l'implémentation par défaut de Go traite les données par blocs de 128 bits.
Pour résoudre le problème et garantir que Go puisse déchiffrer les textes chiffrés cryptés à l'aide des paramètres AES-CFB de Pycrypto, il faut modifier CFBEncrypter / CFBDecrypter de Go pour être compatible avec les segments 8 bits. L'exemple Go fourni s'appuie sur le code de ces fonctions pour effectuer le chiffrement CFB.
Cette personnalisation implique :
La mise en œuvre d'une fonction NewCFBDecrypter personnalisée qui définit la taille du segment à 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 }
Modification de la fonction XORKeyStream pour traiter les données dans Morceaux de 8 bits au lieu de blocs de 128 bits :
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:]) } }
Avec ces modifications, l'exemple Go devrait produire le même texte chiffré que l'implémentation 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
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!