내가 파이썬 코드에서 한 일을 파이썬에서 AES-256-CCM
사용하여 암호화 된 PHP에서 chiphertext를 해독하려고하는 메신저 cryptography.hazmat
는 다음과 같습니다.
from cryptography.hazmat.primitives.ciphers.aead import AESCCM
from os import urandom
import base64
#Text To Encrypt
plaintext = bytes("message from python", encoding='utf-8')
#AES 256 Key Genrator
key = AESCCM.generate_key(256)
#Genrate Nonce
nonce= urandom(12)
#chipher
cipher = AESCCM(key, tag_length=8)
#Encryption
ciphertext = cipher.encrypt(nonce, plaintext, None)
그런 다음 key
, nonce
및 ciphertext
base64 로 변환합니다 .
key_b64 = base64.standard_b64encode(key)
ciphertext_b64 = base64.standard_b64encode(ciphertext)
nonce_b64 = base64.standard_b64encode(nonce)
내 예에서 나는이 결과를 얻었다
key = b'\xcb\x14\x96{,0(\x15\x86 \xda\xf8\x1b"i|M\xbd\xc5d\xe7\xa6I\xdf\x7f\xe11\xae\xe8\x8a\xb3j'
key_b64 = b'yxSWeywwKBWGINr4GyJpfE29xWTnpknff+ExruiKs2o='
nonce = b'\xc7f\xdc\xe3\xe4\x03>M\x9by\x92\x9d
nonce_b64 = b'x2bc4+QDPk2beZKd'
ciphertext = b'R\x9f\xe6D\\_\xdexC\x82\xf8\x8e\x9b;\x91\xc7OLo\xc2\t/\x8fV>G='
ciphertext_b64 = b'Up/mRFxf3nhDgviOmzuRx09Mb8IJL49WPkc9'
내 PHP 코드에서 base64 결과를 사용합니다.
<?php
$key_from_python = base64_decode('yxSWeywwKBWGINr4GyJpfE29xWTnpknff+ExruiKs2o=');
$ciphertext_from_python = base64_decode('ooGUzo0YiwKPs9+2wXySYEpdBNfSpyLUHm1M');
$nonce_from_python = base64_decode('Up/x2bc4+QDPk2beZKd');
$cipher = "aes-256-ccm";
if (in_array($cipher, openssl_get_cipher_methods())){
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$decrypted_mesage_from_pythom =
openssl_decrypt($encrypted_from_python_,$cipher,$key_from_python,$options=0 , $iv, $tag);
echo $decrypted_mesage_from_pythom;
}
여기 http://php.babo.ist/#/en/function.openssl-encrypt.html에서 찾은 예제를 기반으로 하고 해독 프로세스가 아무것도 반환하지 않는 다른 예제를 찾을 수 없으며
실제로 나를 혼란스럽게하는 것은 다음과 같습니다.
$tag
PHP에서 PHP 코드와 $ tag_lenght 모두 대표하는 파이썬 (암호 = AESCCM (키, tag_length = 8))?nonce
에 내 PHP 코드에서 사용하는 방법이 필요한 경우 ?이 작품을 얻는 방법? Python에서 암호화하고 PHP에서 동일한 chiphertext를 해독합니다.
참고 : 암호화에는 python을, 암호 해독에는 php를 사용해야하며 AES-CCM을 사용해야합니다. 파이썬 코드가 수정되었습니다. 이해해 주셔서 감사합니다.
감사합니다
12
잘못된 암호문 / 태그를 초래 하는 임시 바이트 길이 (OP에서 사용)에 대한 AES-CCM의 PHP 구현에 버그가있는 것 같습니다 . 그러나이 버그는 OP의 PHP 코드에있는 여러 결함으로 인해 숨겨져 있습니다. 따라서 이러한 결함을 먼저 수정해야합니다.
OPENSSL_RAW_DATA
암호문이 Base64 인코딩이 아닌 원시 데이터로 전달되면 플래그를 설정해야합니다.이러한 점을 고려한 PHP 구현은 다음과 같습니다.
<?php
// Data from Python code
$key_from_python = base64_decode('<Base64 encoded key from Python>');
$ciphertext_from_python = base64_decode('<Base64 encoded (ciphertext + tag) from Python>');
$nonce_from_python = base64_decode('<Base64 encoded nonce from Python>');
$cipher = 'aes-256-ccm';
// Separate ciphertext and tag
$tagLength = 8;
$ciphertext = substr($ciphertext_from_python, 0, -$tagLength);
$tag = substr($ciphertext_from_python, -$tagLength);
// Decrypt
if (in_array($cipher, openssl_get_cipher_methods())){
$decrypted_mesage_from_pythom = openssl_decrypt($ciphertext, $cipher, $key_from_python, OPENSSL_RAW_DATA, $nonce_from_python, $tag);
echo $decrypted_mesage_from_pythom;
}
?>
이 PHP 코드 를 사용하면 nonce의 길이가 12
bytes와 같지 않는 한 Python 코드에서 데이터를 해독 할 수 있습니다 .
Python 및 PHP 구현은 길이 7
가 13
바이트 (둘 다 포함) 인 임시 값 s를 허용합니다. 여기 파이썬 . 12
바이트 임시 값 문제와 관련하여 다음과 같은 결과가 나타납니다. PHP 코드 에서 마지막 바이트 를 제거하여 12
바이트 임시 값이 바이트로 잘 리면 동일한 암호문 / 태그가 생성됩니다. 다음 PHP 코드는 태그 길이 및 바이트 (PHP 버전 7.4.4)에 대해이를 설명합니다.7
5
8
16
<?php
function printCiphertextTag($plaintext, $key, $iv, $taglength){
$encrypted = openssl_encrypt($plaintext, "aes-256-ccm", $key, OPENSSL_RAW_DATA, $iv, $tag, NULL, $taglength);
echo sprintf("tag size: %2s, IV size: %2s, IV (hex): %-' 24s, ciphertext (hex): %s, tag (hex): %s\n", $taglength, strlen($iv), bin2hex($iv), bin2hex($encrypted), bin2hex($tag));
}
$plaintext = 'message from python';
$key = '01234567890123456789012345678901';
$nonce12 = openssl_random_pseudo_bytes(12);
$nonce7 = substr($nonce12, 0, 7);
printCiphertextTag($plaintext, $key, $iv = $nonce12, $taglength = 8);
printCiphertextTag($plaintext, $key, $iv = $nonce7, $taglength = 8);
printCiphertextTag($plaintext, $key, $iv = $nonce12, $taglength = 16);
printCiphertextTag($plaintext, $key, $iv = $nonce7, $taglength = 16);
?>
이 결과는 PHP 구현의 버그를 나타냅니다.
대조적으로 Python 코드 12
는 PHP 코드와 비교하여 바이트 임시 값에 대해 다른 암호문 / 태그를 생성 합니다 (이것이 12
바이트 임시 값 을 사용하는 (수정 된) OP의 PHP 코드가 실패 하는 이유입니다 ). 동일한 매개 변수를 사용하여 Java / BC로 검사 하면 Python 코드 와 동일한 바이트 임시 값에 대해 동일한 암호문 / 태그가 생성되며 12
, 이는 Python 코드의 값을 확인하고 다시 PHP 구현의 버그를 나타냅니다.
편집 : https://bugs.php.net/bug.php?id=79601 여기에 문제를 제출했습니다 . 참고 :이 문제는 관리자 가 비공개 로 설정 했기 때문에 적절한 권한 없이는 열 수 없습니다 (적어도 지금은). 여기 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다