如何使用 C#.NET 的 PEM 文件中的 P-256 密钥计算 ECDSA 签名?

Posted

技术标签:

【中文标题】如何使用 C#.NET 的 PEM 文件中的 P-256 密钥计算 ECDSA 签名?【英文标题】:How to compute the ECDSA signature using a P-256 key in a PEM file using C#.NET? 【发布时间】:2019-06-24 16:12:47 【问题描述】:

我是密码学的新手,我想在 Windows 上使用 C#.NET 对其进行整理

我使用以下命令生成了一个椭圆曲线 P-256(又名 secp256r1 和 prime256v1)密钥:

openssl ecparam –name prime256v1 -genkey –noout –out private.key

我使用以下命令生成了一个证书签名请求:

openssl req –new –key private.key –out certreq.csr –sha256

另一个团队向我发送了一个 base-64 编码的证书作为回应。到目前为止一切顺利。

我现在收到了一些“测试”数据,我需要使用私钥计算其 ECDSA 签名。私钥看起来像:

-----BEGIN EC PRIVATE KEY-----
FunnyHow?LIKEACLOWN?DOIAMUSEYOU?DOIMAKEYOULAUGH?==
-----END EC PRIVATE KEY-----

到目前为止,我一直在努力使用类似于以下的代码:

byte[] cngBlob; // This was calculated based on another *** post
byte[] testData       = "JoePesciWasGreatInGoodfellas";
CngKey cngKey         = CngKey.Import(cngBlob, CngKeyBlobFormat.EccPrivateBlob);
ECDsaCng eCDsaCng     = new ECDsaCng(cngKey);
byte[] signatureECDSA = eCDsaCng.SignData(testData);

我尝试使用私钥文件计算byte[] cngBlob,基于Microsoft CNG | How to import PEM encoded ECDSA private key into MS Key Storage Provider 但是在byte[] signatureECDSA 中没有得到正确答案。

如何从文件中读取私钥,然后使用它来计算测试数据的 ECDSA 签名?

我已经开始深入研究令人着迷的密码学世界,但我需要一些时间来熟悉它。我在正确的轨道上吗?在此期间帮助我解决此问题的任何提示将不胜感激。

【问题讨论】:

您问题中的链接向您展示了如何做到这一点。如果它不起作用,那么您有义务提供不起作用的代码和问题的详细信息。 原来上面的代码是对的。我实际上已经使用 byte[] HashAlgorithm.ComputeHash(byte[] buffer) 计算了测试数据的哈希值,而我试图签名的正是这个哈希值。我没有意识到计算哈希会产生很大的不同。我必须使用的正确调用结果是 byte[] signatureECDSA = eCDsaCng.SignData(testData); 【参考方案1】:

事实证明,上面的代码是正确的方法,但是我犯了一个错误。我实际上已经使用该方法计算了测试数据的哈希

byte[] HashAlgorithm.ComputeHash(byte[] buffer)

我尝试签名的正是测试数据的散列值。我上面的测试数据应该看起来像

     byte[] testData = null;
     using (SHA256 sha256 = SHA256.Create())
     
        testData = sha256.ComputeHash("JoePesciWasGreatInGoodfellas");
     

我没有意识到计算哈希值会产生重大影响。

我必须用来签署散列测试数据的正确调用结果是

byte[] signatureECDSA = eCDsaCng.SignHash(testData);

以下是最终更正后的代码:

byte[] cngBlob; // This was calculated based on another *** post
byte[] testData = null;
using (SHA256 sha256 = SHA256.Create())

    testData = sha256.ComputeHash("JoePesciWasGreatInGoodfellas");

CngKey cngKey         = CngKey.Import(cngBlob, CngKeyBlobFormat.EccPrivateBlob);
ECDsaCng eCDsaCng     = new ECDsaCng(cngKey);
byte[] signatureECDSA = eCDsaCng.SignHash(testData);

注意:如前文所述,请参阅Microsoft CNG | How to import PEM encoded ECDSA private key into MS Key Storage Provider 的优秀信息,了解如何从 PEM 文件中的私钥创建 cngBlob。

【讨论】:

以上是关于如何使用 C#.NET 的 PEM 文件中的 P-256 密钥计算 ECDSA 签名?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用终端将 .p12 文件转换为 .pem 文件?

如何从 .pem 文件将 .p12 密钥添加到 Java Spring?

制作 .p12/.pem 并在本地测试 APNS 的正确方法

如何解决错误“无法加载PEM客户端证书,OpenSSL错误:02001003:系统库:fopen:没有这样的过程”?

如何在 Linux 中转换 SSL 证书

Python p12 到 pem