지난 주말 비밀번호 문제가 있었고 암호문은 다음과 같은 16진수였습니다.
FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9
나는 이것이 REDRYDER 키와 함께 AES/Rijndael 128비트 ECB를 사용하여 암호화되었다고 확신하며 이를 확인하기 위한 솔루션이 게시되었습니다. 일반 텍스트는 FLAG=DAISY입니다. 나는 솔트나 IV 문자열 없이 해독하는 간단한 PHP mcrypt 스크립트를 작성했고 올바르게 해독되었습니다. 그러나 openssl을 사용하려고 하면 일반 텍스트가 표시되지 않습니다.
echo "0: FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9" | xxd -r | openssl aes-128-ecb -d -k REDRYDER -nosalt -nopad ; echo
이것은 단지 일부 이진 데이터를 출력합니다. 또한 바이트 교환을 수행하기 위해 dd conv=swab을 통해 입력을 전달해 보았습니다.
내가 뭘 잘못했나요?
답변1
이 openssl
명령줄 도구는 OpenSSL 라이브러리의 데모입니다. 다소 불규칙한 인터페이스와 열악한 문서가 있습니다. OpenSSL 라이브러리를 테스트하는 것 이외의 용도로는 사용하지 않는 것이 좋습니다. (예, CA를 관리하는 데 익숙한 사람들이 있습니다. openssl
그들의 정신이 걱정됩니다.)
AES비밀번호 대신 키를 사용하세요. AES-128 키는 정확히 16바이트입니다.
이 옵션은 -k
키를 입력으로 허용하지 않고 비밀번호를 허용합니다. 비밀번호는 키를 파생하기 위해 해시됩니다. 기본값은 MD5이며 명령줄 옵션을 사용하여 재정의할 수 있습니다 -md
. 내가 아는 한, 이 내용은 매뉴얼에 문서화되어 있지 않습니다. 소스 코드( apps/enc.c
, 호출 EVP_BytesToKey
) 만 읽으면 됩니다 . MD5 다이제스트는 모든 문자열에서 16바이트 값을 생성하지만 여기서는 해당 값이 사용되지 않습니다. 이 경우 키는 실제로 널 바이트가 있는 REDRYDER\0\0\0\0\0\0\0\0
위치에 있습니다 \0
.
이 옵션을 사용하면 -K
키를 16진수로 전달할 수 있습니다. 키 크기보다 적은 바이트를 전달하면 OpenSSL은 null 바이트로 완료됩니다. 따라서 key 를 전달하려면 를 REDRYDER\0\0\0\0\0\0\0\0
전달할 수 있습니다 .$(echo REDRYDER | od -An -tx1 | tr -d ' ')
5245445259444552
52454452594445520000000000000000 키를 사용하여 암호문 블록 FC89BFC2B05F1C2E64B8784392783AC9에서 AES-128-ECB 암호 해독 작업을 수행하고 464c41473d444149535900000000000을 얻습니다. 0(16진수 바이트 시퀀스로 표시). 그건 FLAG=DAISY\0\0\0\0\0\0
.
이와 같은 소규모 암호화 작업의 경우 Python 최상위 수준을 사용하는 것을 좋아합니다.암호화폐도서관.
>>> from binascii import hexlify, unhexlify
>>> from Crypto.Cipher import AES
>>> ciphertext = unhexlify('FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9'.replace(' ', ''))
>>> key = 'REDRYDER'.ljust(16, '\0')
>>> AES.new(key, AES.MODE_ECB).decrypt(ciphertext)
'FLAG=DAISY\x00\x00\x00\x00\x00\x00'
답변2
이것은 작동합니다:
echo '0: FC89BFC2B05F1C2E64B8784392783AC9' | xxd -r | openssl enc -aes-128-ecb -d -nopad -nosalt -K 5245445259444552
-k 옵션에 대한 입력을 이해하지 못하지만 일반 텍스트 키를 16진수(올바른 바이트 순서)로 변환하고 대신 -K를 사용하면 작동합니다.
openssl은 부두입니다!