3

I'm trying to create a signature verification system that uses my website which runs on the Google API with PyCrypto Engine. The program that generates signature is quite simple:

from Crypto.PublicKey import RSA
from Crypto.Hash import MD5
def sign(key, message):
   digest = MD5.new(message).digest()
   signature = key.sign( digest, None )[0]
   signature = hex(signature).replace("0x","").replace("L","").upper()
   if len(signature) % 2==1:
      signature = "0" + sig 
   return signature

The key 'key' is provided by:

RSA.construct((m, e, d, p, q))

The signature is returned as a hex string, such as: "A12D......."

.NET program is:

    Private Function Verify(ByVal message As String, ByVal sign As String) As Boolean
    Dim md5 As New MD5CryptoServiceProvider
    Dim f As New StreamReader("D:/KEY.XML")
    Dim xml As String = f.ReadToEnd
    f.Close()

    Dim rsa As New RSACryptoServiceProvider
    rsa.FromXmlString(xml)

    Dim msg_as_bytes As Byte() = Encoding.Default.GetBytes(message)
    Dim hash_as_bytes As Byte() = md5.ComputeHash(msg_as_bytes)

    ''Dim sig_as_bytes As Byte() = convtobytes(sign)

    Dim sig_as_bytes As Byte() = New Byte(sign.Length / 2 - 1) {}
    For i As Integer = 1 To sign.Length / 2
        sig_as_bytes(i - 1) = CByte("&H" & Mid(sign, (i - 1) * 2 + 1, 2))
    Next

    Return rsa.VerifyData(hash_as_bytes, "SHA1", sig_as_bytes)
End Function

But it does not work!!! Why??

Pycrypto and .NET receive the same parameters (modulus, exponent, d, p, q)

Craig McQueen
  • 41,871
  • 30
  • 130
  • 181

2 Answers2

4

I finished!

The solution is to use Crypto.Signature.PKCS1_v1_5

from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Util import number
from Crypto.Signature import PKCS1_v1_5

m = 123....
e = 1111....
d = 123....
p = 365...
q = 657...

key = RSA.construct((m, e, d, p, q))

message = "message to be signed"

def assina(message):
    h = SHA.new(message)
    signer = PKCS1_v1_5.new(key)
    signature = signer.sign(h)
    return ByteToHex(signature)

And .NET code to verify:

Private Function Verify(ByVal message As String, ByVal sign As String) As Boolean
    Dim rsa As New RSACryptoServiceProvider()
    rsa.FromXmlString(_pubKey)

    Dim msg_as_bytes As Byte() = Encoding.Default.GetBytes(message)

    Dim sig_as_bytes As Byte() = New Byte(CInt(sign.Length / 2) - 1) {}

    For i As Integer = 1 To sign.Length / 2
        sig_as_bytes(i - 1) = CByte("&H" & Mid(sign, (i - 1) * 2 + 1, 2))
    Next

    Return rsa.VerifyData(msg_as_bytes, "SHA", sig_as_bytes)
End Function
1

Look at both lines:

digest = MD5.new(message).digest()

Return rsa.VerifyData(hash_as_bytes, "SHA1", sig_as_bytes)

Even if you're using a MD5CryptoServiceProvider in your .NET code your still asking the verification to use SHA1 and that won't work. Try changing this to MD5.

poupou
  • 43,413
  • 6
  • 77
  • 174
  • not work... rsa.VerifyData(hash_as_bytes, "MD5", sig_as_bytes) – Neyton Luiz Dalle Molle Apr 13 '12 at 13:58
  • BitConverter.ToString(rsa.SignData(hash_as_bytes, "MD5")).Replace("-", "") not equal of value returned by python function .... – Neyton Luiz Dalle Molle Apr 13 '12 at 14:44
  • Digital signature using RSA use padding (e.g. PKCS#1 or OAEP) which includes random data. As such you cannot expect the same value out of `SignData` – poupou Apr 13 '12 at 14:54
  • ok, so why the program. NET does not return TRUE as expected? .NET fix: rsa.VerifyData (hash_as_bytes, "MD5", sig_as_bytes) – Neyton Luiz Dalle Molle Apr 13 '12 at 15:07
  • I made this changes, but not work, and signatures in pycrypto and .net not equal... – Neyton Luiz Dalle Molle Apr 16 '12 at 23:45
  • That simply means it was not the **only** error you had. I can't help you with python (nor much vb.net) but make sure your padding (PKCS1 or OAEP) are identical and that your hash values are also identical (otherwise your signature validation will never work). – poupou Apr 17 '12 at 01:11
  • @poupou, Hello, I've been having a similar problem here: http://stackoverflow.com/questions/10329147/trying-to-generate-rsa-signature-with-python-from-working-c-sharp-code/10332841#10332841. I was wondering if you wouldn't mind helping. Thanks ! – mowwwalker Apr 26 '12 at 23:32
  • Hello, I have post this link with the problem: https://dl.dropbox.com/u/26155911/pythonSignNetVerify.zip It has a version of the two codes for a better understanding – Neyton Luiz Dalle Molle Jun 15 '12 at 19:17
  • Better to use `SHA256` in both Python and C#. – Craig McQueen Jun 17 '15 at 01:36