python

时间:2015-07-28 14:40:16

标签: c# python xml-parsing private-key

对于银行交易实施,我有一个私钥和一些数据,我需要使用私钥对该数据进行签名。

银行给出的示例代码是在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中找不到任何好的等价物,我需要做一些确切的事情,以免引发任何异常。我曾经在另一篇文献中提出过这个问题并且被搁置了。我不知道他们为什么这样做,但我已经挣扎了几个星期,我还没有找到任何解决方案。所以请以任何方式帮助我。提前谢谢。

3 个答案:

答案 0 :(得分:4)

请注意示例代码使用SHA1而不是SHA256。

如果您想一次,也可以使用在线RSA密钥转换器工具将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'))

答案 1 :(得分:3)

您需要将.NET XML格式密钥转换为.PEM才能由任何Python模块处理。 (见this question

完成后,您可以使用RSAPyCrypto模块。

使用PyCrypto查看此example code以获取签名数据:

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)

显然,它需要根据您的需求进行调整(例如,如果您需要SHA-1,请使用import SHA代替import SHA256),但它应该会给您一个良好的开端。

答案 2 :(得分:1)

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.sign向您展示了如何在RSA中签名消息,您将需要SHA-1哈希方法。然后base64对结果https://docs.python.org/2/library/base64.html

进行编码