【问题标题】:PHP encrypt and decrypt function to pythonPHP加密和解密函数到python
【发布时间】:2020-12-31 07:09:27
【问题描述】:

我正在与一些服务器进行集成,他们为我提供了他们的 APi 端点以及如何进行集成的代码示例。

在集成的某些步骤中,他们需要在发送数据之前加密数据并解密响应。他们在 PHP 7.3 中为我提供了以下代码:

// function use for encryption
function encrypt($text, $key, $type, $iv = "0123456789abcdef",
$size = 16) {
$pad = $size - (strlen($text) % $size);
$padtext = $text . str_repeat(chr($pad), $pad);
$crypt = openssl_encrypt($padtext, "AES-256-CBC", base64_decode($key), OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
return base64_encode($crypt);

// function use for Decryption
function decrypt($crypt, $key, $type, $iv = "0123456789abcdef") {
$crypt = base64_decode($crypt);
$padtext = openssl_decrypt($crypt, "AES-256-CBC", base64_decode($key), OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
$pad = ord($padtext
{
strlen($padtext) - 1});
if ($pad > strlen($padtext)) {
return false;
}

if (strspn($padtext, $padtext
{
strlen($padtext) - 1}, strlen($padtext) - $pad) != $pad) {
$text = "Error";
}

$text = substr($padtext, 0, -1 * $pad);
return $text;
}

我的应用程序正在使用 python,我正在尝试在 python 中模拟这两个函数,但我对 PHP 了解不多,所以这是我到目前为止所做的,但我仍然评论了一些我不知道的代码不知道用python替换它。

这是我的 python 尝试:

from base64 import b64decode
from Crypto.Cipher import AES
def encrypt(text, key, type, iv = "0123456789abcdef",size = 16):
    pad = size - (len(text)%size)
    # padtext = text . str_repeat(chr(pad), pad)
    crypt=AES.new(padtext,AES.MODE_CBC,b64decode(key),iv)
    return b64decode(crypt)

def decrypt(crypt,key, type, iv = "0123456789abcdef"):
    crypt = b64decode(crypt)
    padtext = AES.new(crypt, AES.MODE_CBC, b64decode(key), iv)
    # $pad = ord($padtext
    # {
    #     strlen($padtext) - 1});
    # if ($pad > strlen($padtext)) {
    # return false;
    # }
    if pad > len(padtext):
        return False
    # if (strspn($padtext, $padtext
    # {
    # strlen($padtext) - 1}, strlen($padtext) - $pad) != $pad) {
    # $text = "Error";
    # }

    # text = substr(padtext, 0, -1 * pad)
    return text

【问题讨论】:

  • 在我看来非常像 PKCS#7 兼容的填充。我不知道他们为什么不只是在 PHP 中使用它,也许是他们使用 mcrypt 函数时的遗留物。在这种情况下,您可能可以将代码替换为 。尽管您当然应该调用一些执行实际加密/解密的方法。
  • 我不明白,请用 替换代码是什么意思?@MaartenBodewes
  • 填充/取消填充很可能已经由 AES 对象上定义的任何加密/解密例程执行。所以你不需要单独实现它。目前你甚至没有加密/解密。
  • 尝试加密/解密,你已经愿意了吗?如果它不起作用,请回来。
  • 根据import 声明,可能应该使用PyCryptodome,它不隐含填充,但提供module to support PKCS7,因此不需要自定义实现。关于 PHP 代码的大部分内容已经被提及:openssl 默认情况下 使用 PKCS7 填充(除非被 OPENSSL_ZERO_PADDING 禁用)。此外,PHP 代码的 encrypt 函数返回填充的明文,这没有任何意义(可能是复制/粘贴错误或某些测试的残余)。

标签: python php python-3.x encryption


【解决方案1】:

经过多次尝试,它非常简单,我设法让它工作

import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad


class AESCipher(object):

    def __init__(self, key):
        self.key = base64.b64decode(key)

    def encrypt(self, raw):
        raw = pad(bytes(raw.encode('utf-8')), 16)
        iv = b'0123456789abcdef'
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(cipher.encrypt(raw))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = b'0123456789abcdef'
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return cipher.decrypt(enc).decode('utf-8')

【讨论】:

  • 这不是一个好的解决方案。保持 iv 相同只会一直产生相同的哈希值。 iv 需要在每次加密时是随机的,因此每次都会产生不同的哈希值。
  • 仅供测试,模拟php
猜你喜欢
  • 2012-10-14
  • 1970-01-01
  • 2015-02-24
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多