【问题标题】:RSA public key decryption c# (powershell)RSA公钥解密c#(powershell)
【发布时间】:2018-12-10 09:20:40
【问题描述】:

我们有一个签名服务,它接受 sha256 哈希作为输入,并使用 pkcs11 对哈希进行签名,C# 中的充气城堡库将签名摘要编码为 Bae64,并将其发送给请求者。所以,本质上我们是在生成一个散列的散列并对散列进行签名。

另一端的请求者为了验证这一点,对接收到的 base64 摘要进行解码并进行验证。我在 PowerShell 中使用了一个 .NET 库,并实现了一个验证过程。请看下文。

## Load a certificate Public key and verify

$certusedforsigning = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2

$certusedforsigning.Import($signingcertificate)

$certusedforsigning.PublicKey.key  -as [System.Security.Cryptography.RSACryptoServiceProvider] | Out-null

$oid = [System.Security.Cryptography.CryptoConfig]::MapNameToOID('SHA256')

$padding = [System.Security.Cryptography.RSASignaturePadding]::Pkcs1

$result = $certusedforsigning.PublicKey.key.Verifyhash($originalhashinBinary,$signedbinary,'SHA256',$padding)

$result

if($result -eq 'True' ) { write-host 'Signature verified True'} else { write-host 'Signature validation Failed'}

}
}

现在,为了绕过散列散列,我们使用 RSA 私钥对接收到的 sha256 散列进行加密。现在我假设我需要使用公钥解密哈希,生成原始消息的 sha256 哈希并比较两者以验证。

.NET 中是否有可以让我这样做的方法或函数?我可以使用 OpenSSL 完成此操作吗?你能告诉我如何完成上述验证这样的消息吗?谢谢。

【问题讨论】:

标签: c# powershell cryptography rsa signing


【解决方案1】:

通常没有明确定义使用私钥进行加密。有两种 PKCS#1 v1.5 填充方法:一种用于签名(使用私钥),另一种用于加密(使用公钥)。所以这取决于使用哪种填充方法的实现。

假设使用了用于签名的那个。检查这一点很容易:只需在相同数据上重新生成签名。如果它与前一个相同,则选择签名填充(PKCS#11 实现按密钥类型选择)。

要验证签名,您只需对数据进行哈希处理,然后执行签名验证(在 C# 中可以包括哈希处理)并根据 base 64 解码签名值进行验证。除此之外,不需要任何特定的魔法。

如果使用了非确定性加密方案,那么您可能需要重新考虑您的协议。 RSA 填充是 RSA 密码系统提供的安全性的核心。

【讨论】:

  • 嗨 Maarten,感谢您的更新....net api 中的加密服务提供程序类不会让我解密加密消息和 pkcs1 填充。正如预期的那样,当您尝试验证使用公钥加密的消息时,验证失败。
  • 那么可能使用了错误的填充。您可以尝试使用 raw RSA 解密签名,因此您可以查看并与 PKCS#1 进行比较(有一个 RFC 3447 定义了包含填充方法的 RSA)。我认为您的意思是*使用私钥加密并使用公钥验证,对吧?
  • 嗨,Maarten,'Raw RSA',会做一些研究来找出哪个库支持它,如果你能指出我的话,我很高兴。是的,这是一个错字,我的意思是使用私钥加密并使用公钥进行验证。但是,从您的评论和其他人中发现 pkcs1 填充模式与签名与加密不同,因此加密的摘要不同。您只能加密 RSAkeysize-11bytes 的消息,即填充大小。