Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用AES-256-CCM在php中解密python加密的文本_Python_Php_Cryptography_Aes - Fatal编程技术网

如何使用AES-256-CCM在php中解密python加密的文本

如何使用AES-256-CCM在php中解密python加密的文本,python,php,cryptography,aes,Python,Php,Cryptography,Aes,我正在尝试用PHP解密一条chiphertext,它是用python中的cryptography.hazmat用AES-256-CCM加密的 我在python代码中所做的是: from cryptography.hazmat.primitives.ciphers.aead import AESCCM from os import urandom import base64 #Text To Encrypt plaintext = bytes("message from python", enc

我正在尝试用PHP解密一条chiphertext,它是用python中的
cryptography.hazmat
AES-256-CCM
加密的 我在python代码中所做的是:

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)
然后我将
nonce
密文
转换为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;
}

AES-CCM的PHP实现中似乎存在一个错误,当前长度为
12
字节(由OP使用),这会导致错误的密文/标记。然而,OP的PHP代码中的许多缺陷隐藏了这个bug。因此,必须首先修复这些缺陷:

  • Python和PHP实现的不同之处在于,在Python代码中,密文和标记按顺序连接,而在PHP代码中,密文和标记分别处理
  • Python代码中的nonce对应于PHP代码中的IV
  • 在PHP代码中,如果密文作为原始数据传递而不是Base64编码,则必须设置
    OPENSSL_RAW_DATA
    标志
  • nonce和ciphertext(+tag)的值在两种代码中都不同。然而,由于选择了12字节的nonce,加上12字节nonce的PHP错误,因此更正是没有意义的,请参见下文。即,成功测试的先决条件是一个不等于12字节的nonce大小
考虑到这些点的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实现中存在错误

相比之下,Python代码为
12
字节的nonce与PHP代码生成不同的密文/标记(这就是为什么(更正的)OP的PHP代码使用
12
字节的nonce失败的原因)。使用具有相同参数的Java/BC进行检查会为
12
字节的nonce生成与Python代码相同的密文/标记,这将验证Python代码的值,并再次表明PHP实现中存在错误


编辑:我在这里提交了一个问题:。注意:该问题由管理员设置为私有,因此在没有适当权限的情况下无法打开(至少目前是这样)

您的PHP代码充满了如此多的错误,如此多的数据被误译或完全破坏,以至于无法提供任何有用的信息。有一件事我可以肯定地说,你需要在PHP中打开错误报告,这样你就可以看到你的代码生成的错误页面。如果我全部在PHP中进行解密和加密,则解密和加密工作正常,但如果我尝试用python解密加密的内容,则无法工作,关于数据,我将所有内容转换为base64,以避免丢失数据,是的,错误报告已打开,没有错误报告。请告诉我php中的错误是什么,至少是主要错误。您运行的php必须与您发布的非常不同。我敢打赌python中的
nonce
就是PHP中的
iv
。如果您想看到错误,只需复制/粘贴您发布的PHP并尝试运行它。变量被使用但未初始化,变量名中的输入错误,密文和nonce完全被错误转录,甚至在修复了密文长度不正确的问题后。如果你仔细阅读了我的问题,你会很清楚我在寻找什么,问题是,在python中我们有
nonce
ciphertext
但是在PHP中它需要
$tag
$IV
$ciphertext
和可选的
$tag\u length
,如果
nonce
被错误转录,你能给我一个更好的方法在PHP中重用吗,它给你错误的原因是它需要定义
$tag
,这就是为什么我首先问这个问题,tag代表什么,如果你把
IV
当作
nonce
什么是
tag
,那么如果你把
tag
当作
nonce
我们该怎么办呢?
<?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);
?>