c# - 从ECDSA签名signedxml中提取r和s#

标签 c# cryptography digital-signature ecdsa signedxml

我正在使用 .net 5 中的 Signedxml 类来使用 ECDSA 生成签名 我需要 r 和 s 的值,但我无法提取它,另一个问题是 签名长度。我的签名始终是 64 字节,但 ECDSA 签名长度是 71 而且我不知道为什么这个长度会改变。请帮我提取 r 和 s

最佳答案

将 ECDSA 签名从 ASN.1/DER 转换为 P1363 (r|s) 格式时,必须考虑以下因素:

  • 在 ASN.1/DER 格式中,r 和 s 包含为有符号、大端数组,在 P1363 格式中,包含为无符号、大端数组。
  • 在 ASN.1/DER 格式中,r 和 s 被包含为最小尺寸数组,在 P1363 中,两者都被填充到其最大尺寸(生成器点),具有前导 0x00 值。示例:对于 NIST P-256,r 和 s 的最大大小均为 32 字节。

使用 AsnReader 类在 .NET 5+ 上的可能实现:

using System.Formats.Asn1;
...
public static byte[] DERtoP1363(byte[] derSignature, int maxSize)
{
    AsnReader sequence = new AsnReader(derSignature, AsnEncodingRules.DER).ReadSequence();
    byte[] rBytes = sequence.ReadInteger().ToByteArray(true, true); // convert to unsigned, big endian
    byte[] sBytes = sequence.ReadInteger().ToByteArray(true, true); // convert to unsigned, big endian
    byte[] rsBytes = new byte[2 * maxSize];
    Buffer.BlockCopy(rBytes, 0, rsBytes, maxSize - rBytes.Length, rBytes.Length);     // resize to maximum size
    Buffer.BlockCopy(sBytes, 0, rsBytes, 2 * maxSize - sBytes.Length, sBytes.Length); // resize to maximum size
    return rsBytes;
}

AsnReader 自 .NET 5 起可用。

为了完整性:在其他 .NET 版本中,可以应用 BouncyCaSTLe(使用 Org.BouncyCaSTLe.Asn1 命名空间中的类)。为此,DERtoP1363() 中的前三行必须替换为:

Asn1Sequence sequence = Asn1Sequence.GetInstance(derSignature);
byte[] rBytes = DerInteger.GetInstance(sequence[0]).PositiveValue.ToByteArrayUnsigned();
byte[] sBytes = DerInteger.GetInstance(sequence[1]).PositiveValue.ToByteArrayUnsigned();

关于c# - 从ECDSA签名signedxml中提取r和s#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72309826/

相关文章:

c# - ASP.NET - 单一解决方案、MVC 和 WebApi 项目,每个项目都有单独的模型?

c# - TripleDES 16 字节不工作

c# - 撤销证书验证中的 X509RevocationMode.Online 问题

c# - 字符串格式化 C# 解码?

c# - 如何仅通过 userinfo 端点而不是访问 token 获取声明

c# - 如何在 TreeView 中获取子位置?

python - 安全的加密签名必须驻留在它所引用的文件之外吗?

c# - 解密 TripleDES : Specified key is a known weak key and cannot be used

c++ - 关于为许可证系统创建 key 生成器的问题

java - 使用 Java 向 PDF 添加数字签名