PHP openssl_get_privatekey и openssl_sign в Python - PullRequest
0 голосов
/ 12 июня 2019

Кто-нибудь знает, что эквивалентно этим двум строкам PHP-кода в Python?

$pkeyid = openssl_get_privatekey($priv_key);
openssl_sign($data, $binary_signature, $pkeyid, OPENSSL_ALGO_SHA1);

Заранее спасибо!

Отредактировано:

$fpx_msgToken = "01";
$fpx_msgType = "BE";
$fpx_sellerExId = "ABC000012345";
$fpx_version = "6.0";
/* Generating signing String */
$data = $fpx_msgToken."|".$fpx_msgType."|".$fpx_sellerExId."|".$fpx_version;
/* Reading key */
$priv_key = file_get_contents('C:\\pki-keys\\DevExchange\\EX00002220.key');
$pkeyid = openssl_get_privatekey($priv_key);
openssl_sign($data, $binary_signature, $pkeyid, OPENSSL_ALGO_SHA1);
$fpx_checkSum = strtoupper(bin2hex( $binary_signature ) );

Ответы [ 2 ]

1 голос
/ 12 июня 2019

В Python я бы использовал пакет cryptography.

Показанные примеры можно найти здесь: https://cryptography.io/en/latest/hazmat/primitives/asymmetric/dsa/

Вы можете создать закрытый ключ со следующим кодом.

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import dsa

private_key = dsa.generate_private_key(key_size=2048, backend=default_backend())

Это создаст ключ для генерации подписи ваших данных.

Я бы предложил вам 2048 бит или более для длины ключа.

Следующий код является примером для подписи сообщения.

from cryptography.hazmat.primitives import hashes

data = b"this is some test data"
signature = private_key.sign(data, hashes.SHA256())

Если вы хотите проверить подпись, вам нужно получить открытый ключ из закрытого ключа.

public_key = private_key.public_key()
public_key.verify(signature, data, hashes.SHA256())

Этот открытый ключ соответствует вашему личному ключу и используется для проверки подписей, которые были созданы с вашим личным ключом.

Не сосредотачивайтесь на каждой строке слишком много, у каждого языка и библиотеки будут разные методы и способы делать в основном одно и то же.

Теперь для полного примера вы можете просто соединить приведенные выше примеры.

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dsa

private_key = dsa.generate_private_key(key_size=2048, backend=default_backend())
data = b"this is some test data"
signature = private_key.sign(data, hashes.SHA256())
public_key = private_key.public_key()
public_key.verify(signature, data, hashes.SHA256())

public_key.verify() вызовет исключение InvalidSignature, если подпись окажется недействительной (Источник: https://cryptography.io/en/latest/hazmat/primitives/asymmetric/dsa/#verification).

0 голосов
/ 13 июня 2019

Я нашел решение кода, эквивалентного Python для приведенного выше кода PHP, как показано ниже.

from OpenSSL import crypto
import binascii    

fpx_msg_token = "01"
fpx_msg_type = "BE"
fpx_seller_exchange_id = "ABC0000123"
fpx_version = "6.0"

# Generating signing String
data = "{}|{}|{}|{}".format(fpx_msg_token, fpx_msg_type, fpx_seller_exchange_id, fpx_version)

key_id = open('C:\\pki-keys\\DevExchange\\EX00002220.key').read();

# Check is TraditionalOpenSSL or PKCS8 format 
if key_id.startswith('-----BEGIN RSA PRIVATE KEY'):
    # TraditionalOpenSSL format;
    priv_key = crypto.load_privatekey(crypto.FILETYPE_PEM, key_id)
else:
    # PKCS8 format;
    priv_key = crypto.load_pkcs12(key_id).get_privatekey()

# return signature is in binary string;
signature_bin_str = crypto.sign(priv_key, data, 'sha1')

# Convert binary string to hexidecimal
signature_hex = binascii.hexlify(signature_bin_str)

# Convert binary to string;
signature = signature_hex.decode("ascii")

# Convert signature to upper case;
fpx_checksum = str(signature).upper()

В конце я получил то же значение, что и в коде PHP.

:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...