Reputation: 71
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)
Upvotes: 3
Views: 1880
Reputation: 71
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
Upvotes: 4
Reputation: 43543
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
.
Upvotes: 1