Что эквивалентно этому в питоне
Для реализации банковской транзакции у меня есть закрытый ключ и некоторые данные, и мне нужно подписать эти данные с помощью закрытого ключа.
Пример кода, который банк дал, находится на C# .NET, и я не могу найти никакого эквивалента в Python.
Ключ в следующем формате:
<RSAKeyValue>
<Modulus>...</Modulus>
<Exponent>...</Exponent>
<P>...</P>
<Q>...</Q>
<DP>...</DP>
<DQ>...</DQ>
<InverseQ>...</InverseQ>
<D>...</D>
</RSAKeyValue>
И пример кода такой:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(“ <RSAKeyValue><Modulus>oQRshGhLf2Fh... ”);
string data = "#" + merchantCode + "#" + terminalCode + "#"
+invoiceNumber + "#" + invoiceDate + "#" + amount + "#" +redirectAddress
+ "#" + action + "#" + timeStamp + "#";
byte[] signMain = rsa.SignData(Encoding.UTF8.GetBytes(data), new
SHA1CryptoServiceProvider());
sign = Convert.ToBase64String(signMain);
Сейчас я не нашел хорошего эквивалента для этого в Python, и мне нужно сделать точную вещь, чтобы не вызывать никаких исключений. Однажды я задал этот вопрос в другой литературе, и он был отложен. Я не знаю, почему они это сделали, но я боролся с этим в течение нескольких недель, и я пока не нашел никаких решений. пожалуйста, помогите мне, чем сможете. заранее спасибо.
2 ответа
Вам нужно будет преобразовать ключ формата.NET XML в.PEM, чтобы он мог обрабатываться любыми модулями Python. (См. Этот вопрос)
Если у вас есть это, вы можете использовать модули RSA или PyCrypto.
Проверьте этот пример кода для подписи данных с помощью PyCrypto:
def sign_data(private_key_loc, data):
'''
param: private_key_loc Path to your private key
param: package Data to be signed
return: base64 encoded signature
'''
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from base64 import b64encode, b64decode
key = open(private_key_loc, "r").read()
rsakey = RSA.importKey(key)
signer = PKCS1_v1_5.new(rsakey)
digest = SHA256.new()
# It's being assumed the data is base64 encoded, so it's decoded before updating the digest
digest.update(b64decode(data))
sign = signer.sign(digest)
return b64encode(sign)
Очевидно, что он должен быть адаптирован к вашим потребностям import SHA
вместо import SHA256
например, если вам нужен SHA-1), но это должно дать вам хороший старт.
Обратите внимание, что в примере кода используется SHA1, а не SHA256.
Также вы можете использовать онлайн-инструмент RSA Key Converter для преобразования формата RSA xml в формат.pem, если хотите сделать это один раз.
Вы можете использовать этот метод:
import json
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA1
import base64 import
def get_sign(data, private_key):
rsa_key = RSA.importKey(base64.b64decode(private_key.encode("utf-8")))
signer = PKCS1_v1_5.new(rsa_key)
digest = SHA1.new()
digest.update(data)
sign = signer.sign(digest)
return base64.b64encode(sign).decode('utf-8')
# usage example
pem_private_key= """
izfrNTmQLnfsLzi2Wb9xPz2Qj9fQYGgeug3N2MkDuVHwpPcgkhHkJgCQuuvT+qZI
...
eM1tfdFZ6wMTLkxRhBkBK4JiMiUMvpERyPib6a2L6iXTfH+3RUDS6A==
"""
payload_json = json.dumps({"is_example":True})
sign = get_sign(pem_private_key, payload_json.encode('utf-8'))
https://pypi.python.org/pypi/rsa является реализацией RSA. Я не знаю, что, черт возьми, происходит в этой rsa.FromXmlString ( https://msdn.microsoft.com/en-us/library/vstudio/system.security.cryptography.rsa.fromxmlstring(v=vs.90)), так что потребуется некоторое расследование с вашей стороны.
http://stuvel.eu/files/python-rsa-doc/reference.html показывает, как подписать сообщение в RSA, вам понадобится хеш-метод SHA-1. Затем base64 кодирует результаты https://docs.python.org/2/library/base64.html