> 백엔드 개발 > Golang > AES-CFB를 사용할 때 Go와 Pycrypto가 서로 다른 암호문을 생성하는 이유는 무엇이며, 이 문제를 어떻게 해결할 수 있습니까?

AES-CFB를 사용할 때 Go와 Pycrypto가 서로 다른 암호문을 생성하는 이유는 무엇이며, 이 문제를 어떻게 해결할 수 있습니까?

Susan Sarandon
풀어 주다: 2024-12-07 15:37:10
원래의
609명이 탐색했습니다.

Why do Go and Pycrypto produce different ciphertexts when using AES-CFB, and how can this be resolved?

AES-CFB를 사용할 때 Go 및 Pycrypto에서 다른 결과

여기에 제시된 문제는 Go 및 Pycrypto에서 AES-CFB를 사용하여 데이터를 암호화하는 것과 관련됩니다. , 결과적으로 다른 암호문이 생성됩니다. 제공된 Python 및 Go 샘플은 동일한 키, IV 및 일반 텍스트를 사용하지만 매우 별개의 암호화된 데이터를 생성합니다.

Python: dbf6b1877ba903330cb9cf0c4f530d40bf77fe2bf505820e993741c7f698ad6b
Go: db70cd9e6904359cb848410bfa38d7d0a47b594f7eff72d547d3772c9d4f5dbe

각 언어는 자신의 암호문을 해독할 수 있지만 다른 언어의 출력을 해독하지 못하여 방해가 됩니다.

해상도

이런 차이는 Python과 Go에서 CFB 모드에 사용되는 비트 세그먼트 크기가 다르기 때문에 발생합니다. Python은 데이터가 8비트 세그먼트에서 처리되는 CFB8을 활용하는 반면 Go의 기본 구현은 128비트 블록에서 데이터를 처리합니다.

문제를 해결하고 Go가 Pycrypto의 AES-CFB 설정을 사용하여 암호화된 암호문을 해독할 수 있는지 확인하려면, 8비트 세그먼트와 호환되도록 Go의 CFBEncrypter / CFBDecrypter를 수정해야 합니다. 제공된 Go 샘플은 이러한 함수 내의 코드를 사용하여 CFB 암호화를 수행합니다.

이 사용자 정의에는 다음이 포함됩니다.

  1. 세그먼트 크기를 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
    }
    로그인 후 복사
  2. 수정 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿