TL;DR... 如何使用 .Net Framework 4.5.2 使用 PEM 私钥文件创建 DSA 签名
我预先道歉...这对我来说是全新的,因为我从来没有处理过这样的加密。所以请温柔点!
详细信息...
我正在使用 .Net Framework 4.5.2 处理一个旧的 ASP.Net 项目...是的,我非常清楚它已经过时了,但我对此无能为力时间。
我需要将数据发送到 API,其中部分数据(由其他已知数据组成的“签名”)使用 DSA 和客户端提供的私钥进行加密...是的,我非常清楚现在应该使用 RSA,但这正是客户的要求。
私钥已以 PEM 格式文件提供(即文件以 -----BEGIN DSA PRIVATE KEY-----
开头)
我发现了AsnKeyParser class from codeproject.com但到目前为止我还没有弄清楚如何将该类与 PEM 格式文件一起使用。
This (purposefully) confusing answer凸显了我的困惑和缺乏理解。
有人可以告诉我如何实现这一目标,因为我已经浪费了一整天的时间进行调查,但没有取得任何真正的成功?
在将 Base64 解码的证书(在 header 之间)传递给 AsnKeyParser
类之前,我是否需要将其从 DER 转换为 ASN.1?如果是这样,怎么办?
(如有必要,我可以考虑使用更新的 .Net 版本创建外部服务,我可以从 4.5.2 代码中调用该服务...但更希望将其包装到单个项目中。)
编辑...
根据@Topaco的要求,这是客户提供的示例 key 对,他告诉我(有点含糊)根据Google:DSA key 大小:2048位
...
-----BEGIN DSA PRIVATE KEY-----
MIIBugIBAAKBgQDzGuacD99b5uI/yv8k9B0ayApGge79XN18K3NDals1M/ae31Aa
REiT3pM2Vy+rwZqMXkAjdvBRbAAIWULCPmwlJ25IHBg9zZmK0NymS3qaKd5g3LFC
QXRmOLEVhv0TkZAFmi3u71nvDY35hD5S1OlxXp317MIz8U6/usJhtHjQywIVAKAF
qSaXNbaXLei/kNvHeEMxJvPzAoGAcq8gQ4T1o+xkj7ilhEv1XxiAjKJAZao15JOc
G6D9itSkDTZk/4WftDdIwWV8cYCG6PHmbvGi4i/2Z/LIixnuqWJTUG/EpiXf2RAV
47wgUjGmKtIbpUURSGE+XFfYf5R63hmLp2Jn40NqU9OlAScCDEAqN62YB6+Kua71
/ngDzNACgYBUgc3Gw85Amc2BpFruGsUkB4spnonmueq5HV3bcYIxvrO03UTQovTi
8yvQRUPYSIfCzgS2800ntwizZ6NCwUj6lda6YVBZWw8rg7D9HYoD9aOz4GtN57Da
qml0C3Tqh/1wZI5K+lmyDJfex/nQ4iGQoCmzKftWf13x1iCKM08ULwIUZ8Ig9WT9
Q3BcHfdOKLqa3nbYXCw=
-----END DSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBtjCCASsGByqGSM44BAEwggEeAoGBAPMa5pwP31vm4j/K/yT0HRrICkaB7v1c
3Xwrc0NqWzUz9p7fUBpESJPekzZXL6vBmoxeQCN28FFsAAhZQsI+bCUnbkgcGD3N
mYrQ3KZLepop3mDcsUJBdGY4sRWG/RORkAWaLe7vWe8NjfmEPlLU6XFenfXswjPx
Tr+6wmG0eNDLAhUAoAWpJpc1tpct6L+Q28d4QzEm8/MCgYByryBDhPWj7GSPuKWE
S/VfGICMokBlqjXkk5wboP2K1KQNNmT/hZ+0N0jBZXxxgIbo8eZu8aLiL/Zn8siL
Ge6pYlNQb8SmJd/ZEBXjvCBSMaYq0hulRRFIYT5cV9h/lHreGYunYmfjQ2pT06UB
JwIMQCo3rZgHr4q5rvX+eAPM0AOBhAACgYBUgc3Gw85Amc2BpFruGsUkB4spnonm
ueq5HV3bcYIxvrO03UTQovTi8yvQRUPYSIfCzgS2800ntwizZ6NCwUj6lda6YVBZ
Ww8rg7D9HYoD9aOz4GtN57Daqml0C3Tqh/1wZI5K+lmyDJfex/nQ4iGQoCmzKftW
f13x1iCKM08ULw==
-----END PUBLIC KEY-----
最佳答案
对于 DSA,.NET Framework 4.5.2 在 key 大小(最大 1024 位,请参阅 here)和摘要(仅限 SHA1,请参阅 here)方面非常有限。
出于这个原因,从一开始就使用功能更强大的第三方提供商(例如 BouncyCaSTLe)更有意义。 BouncyCaSTLe 还提供 PemReader
以方便导入 PEM 编码 key 。
导入:
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Crypto;
...
string privDsaPem = @"-----BEGIN DSA PRIVATE KEY-----
MII...
-----END DSA PRIVATE KEY-----";
PemReader pemReader = new PemReader(new StringReader(privDsaPem));
AsymmetricCipherKeyPair dsaKeyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
AsymmetricKeyParameter dsaPrivParams = dsaKeyPair.Private;
签名:
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto;
using System;
...
ISigner sig = SignerUtilities.GetSigner("SHA256withDSA");
sig.Init(true, dsaPrivParams);
sig.BlockUpdate(message, 0, message.Length);
byte[] signatureBC = sig.GenerateSignature(); // ASN.1/DER format
Console.WriteLine(Convert.ToBase64String(signatureBC)); // e.g. MEYCIQDDznPDx5YjsszeOvNbvX2pgTDP4qtkOXMlNo+9B9+xsAIhAKOf8G16Z7uFLlevnC1DzUE+Op5XmwoxbK6my/RjEIRG
对于已发布的解决方案适用:
- DSA 签名以 ASN.1/DER 编码格式返回(因此可以加载到 ASN.1 解析器中,例如 https://lapo.it/asn1js/)。
- 应用摘要 SHA256。
关于签名格式和摘要,请考虑以下事项:
DSA 签名由两部分组成:r 和 s,请参阅 here 。 DSA 签名有不同的格式。在上述解决方案中,签名的r和s值以ASN.1/DER编码格式提供。另一种格式是 IEEE P.1363,其中 r 和 s 连接在一起。请参阅here了解两种格式的关系以及它们之间的转换。
除了 SHA256 之外,BouncyCaSTLe 还支持 DSA 的其他摘要,请参阅 SignerUtilities.cs了解更多摘要和标识符。
双方必须应用相同的摘要才能成功验证,并且为了避免不必要的转换,应尽可能使用相同的签名格式。
关于.net - 使用 PEM 文件创建 DSA 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73291553/