微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用 Python 解密用 PHP 加密的密文

如何解决用 Python 解密用 PHP 加密的密文

我有一个使用 PHP 加密的密文,我需要使用 Python 对其进行解密。 我有以下 PHP 代码可以完美地解密密文。

$cryptText = "ciphertext";
$iv = "some iv"
$cipher = new Crypt_Rijndael(CRYPT_RIJNDAEL_MODE_CFB);

$password = "some password";
$salt = "some salt";

$cipher->setPassword($password,'pbkdf2','sha512',$salt,1000,256 / 8);
$cipher->setIV($iv);
$plaintext = $cipher->decrypt(base64_decode($cryptText));

现在使用 Python 解密它,我使用了 2 种方法

  1. 使用pyaes
from base64 import b64encode,b64decode
import hashlib
import pyaes
import os

ciphertext = 'ciphertext'
ciphertext = b64decode(ciphertext)

password = b'some password'
salt = b'some salt'
iv=b'some iv'

key = hashlib.pbkdf2_hmac('sha512',password,salt,32)

aes = pyaes.AESModeOfOperationCFB(key,iv = iv)
decryptedData = aes.decrypt(ciphertext)
  1. PyCryptodome (Crypto.Cipher.AES)
import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES
import hashlib

ciphertext = 'ciphertext'
ciphertext = b64decode(ciphertext)

password = b'some password'
salt = b'some salt'
iv=b'some iv'

key = hashlib.pbkdf2_hmac('sha512',32)

cipher = AES.new(key,AES.MODE_CFB,iv)
decryptedData = cipher.decrypt(ciphertext)

1 和 2 的结果相同但与 PHP 的结果不匹配

解决方法

PHP 代码使用与两个 Python 代码不同的段大小1)phpseclib v1CRYPT_RIJNDAEL_MODE_CFB 指定具有段大小的 CFB 模式128 位(全块 CFB),而 PyCryptodomepyaes 默认使用 8 位的段大小。
因此,可以用 PHP 代码解密的密文无法用任一 Python 代码解密。为此,必须在 Python 代码中将段大小显式设置为 128 位,

  • 对于PyCryptodome

    cipher = AES.new(key,AES.MODE_CFB,iv=iv,segment_size=128)
    
  • 对于pyaes

    cipher = pyaes.AESModeOfOperationCFB(key,segment_size=16)
    

    请注意,对于pyaes,段大小以字节为单位而不是以位为单位指定。此外,pyaes 要求明文必须是段大小的整数倍,即对于全块 CFB 是 16 字节的整数倍。


1) CFB 模式的段大小对应于每个加密步骤加密的位,参见 CFB

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。