.NET RSACryptoServiceProvider 中的 PyCrypto 签名消息和验证签名

Posted

技术标签:

【中文标题】.NET RSACryptoServiceProvider 中的 PyCrypto 签名消息和验证签名【英文标题】:PyCrypto Sign Message and Verify Signature in .NET RSACryptoServiceProvider 【发布时间】:2012-04-13 12:29:20 【问题描述】:

我正在尝试创建一个签名验证系统,该系统使用我的网站,该网站在带有 PyCrypto 引擎的 Google API 上运行。 生成签名的程序很简单:

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

密钥'key'由以下提供:

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

签名以十六进制字符串形式返回,如:“A12D.......”

.NET 程序是:

    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

但它不起作用!为什么??

Pycrypto 和 .NET 接收相同的参数(模数、指数、d、p、q)

【问题讨论】:

【参考方案1】:

我说完了!

解决方案是使用 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)

和.NET代码验证:

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

【讨论】:

您也可以在 Python 中使用 Crypto.Hash.SHA256,在 C# 中使用 rsa.VerifyData(msg_as_bytes, "SHA256", sig_as_bytes)【参考方案2】:

看看这两行:

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

返回 rsa.VerifyData(hash_as_bytes, "SHA1", sig_as_bytes)

即使您在 .NET 代码中使用 MD5CryptoServiceProvider,您仍然会要求验证使用 SHA1,但这是行不通的。尝试将其更改为 MD5

【讨论】:

不工作... rsa.VerifyData(hash_as_bytes, "MD5", sig_as_bytes) BitConverter.ToString(rsa.SignData(hash_as_bytes, "MD5")).Replace("-", "") 不等于 python 函数返回的值 .... 使用 RSA 的数字签名使用包含随机数据的填充(例如 PKCS#1 或 OAEP)。因此,您不能期望 SignData 有相同的值 好的,那为什么是这个程序。 NET 没有按预期返回 TRUE? .NET 修复:rsa.VerifyData (hash_as_bytes, "MD5", sig_as_bytes) 我做了这个更改,但不起作用,并且 pycrypto 和 .net 中的签名不相等...

以上是关于.NET RSACryptoServiceProvider 中的 PyCrypto 签名消息和验证签名的主要内容,如果未能解决你的问题,请参考以下文章

.NET平台系列26:在 Windows 上安装 .NET Core/.NET5/.NET6

[.NET大牛之路 005] .NET 的执行模型

ADO.NET和.NET的关系?

VS2022 安装.NET 3.5/.NET 4/.NET 4.5/.NET 4.5.1目标包的方法

.net core 3.0和.net5有什么区别

能说一下ADO.NET 和.NET,还有asp.NET的区别吗?