我找不到P1363格式确定性的任何参考.rs在确定性模式下总是不同的.

Non-Deterministic带P1363->WithPlain-ECDSA确定

        ISigner sign = SignerUtilities.GetSigner("SHA256WithPlain-ECDSA");            
        sign.Init(true, privateKey);
        sign.BlockUpdate(message, 0, message.Length);
        byte[] signedBytes = sign.GenerateSignature();   // Signature can divded by 2. OK

Deterministic way:(如何申请WithPlain-ECDSA?)

        var signer = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
        signer.Init(true, privateKey);
        var toto = signer.GenerateSignature(message);
        var r = toto[0].ToByteArray();   // sometimes r are equqal s
        var s = toto[1].ToByteArray();   // sometimes s larger than s byte one.

我不能退r.Concat(s).ToArray().在转换成P1363之前,无法将rs转换为byte[]?这在上面的确定性版本中不存在...

  1. 如何在P1363格式的字节[]中连接rs
  2. 如何确保我可以通过将数组的一半转换回r,另一半转换回s.
  3. 有时r等于s,或s大于r,如何确保生成时两者完全相等?

我找不到P1363的任何参考资料.但我发现只有ASN1 DER format个:

    using (MemoryStream ms = new MemoryStream())
        using (Asn1OutputStream asn1stream = new Asn1OutputStream(ms))
        {
            DerSequenceGenerator seq = new DerSequenceGenerator(asn1stream);
            seq.AddObject(new DerInteger(s));
            seq.AddObject(new DerInteger(s));
            seq.Close();
            var arrr =  ms.ToArray();
        }

我也试过这个trick

不完全确定上述人员的技巧是否奏效,但人员try 以固定方式生成:

   Array.Copy(sig1, 0, sig, 0 + (32 - sig1.Length), sig1.Length);
    Array.Copy(sig2, 0, sig, 32 + (32 - sig2.Length), sig2.Length);

Short Answer:

根据@Topaco answer,其快速手动方法.非常感谢他.在调查之后,我们还可以使用两个类StandardDsaEncodingPlainDsaEncoding

  1. StandardDsaEncoding用于编码/解码ASN1.Der格式.
  2. PlainDsaEncoding用于编码/解码P1363格式.

PlainDsaEncoding.Instance.Encode()//此转换为P1363格式.

注意:ECDsaSigner可以包装在DsaDigestSigner中,以允许消息自动散列.或者手动计算散列(消息),然后像@Topaco other post answer一样使用ECDsaSigner.

推荐答案

对于P1363,确定签名是使用确定性ECDSA算法还是非确定性ECDSA算法无关.

在P1363中:

  • r和s包含为无符号的大端数组
  • r和s用前导0x00值填充到其最大大小(生成器点顺序的长度)

在您的代码中,r(toto[0])和s(toto[1])都是Org.BouncyCastle.Math.BigInteger类型.然后可以通过以下方式简单地转换为P1363(为简单起见,不计算最大大小,但传递最大大小):

using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities.Encoders;
using System;

// r and s as BigIntegers
BigInteger r = new BigInteger("184277181267172538606383136781492460232995304963063764346199145255201368533");
BigInteger s = new BigInteger("59980738789003505646930326203273200546254161299399868639304126982806381806190");

// Convert to unsigned, big endian arrays
var rBytes = r.ToByteArrayUnsigned();
var sBytes = s.ToByteArrayUnsigned(); 

// Pad to maximum size 
int maxSize = 32;
byte[] rsBytes = new byte[2 * maxSize];
Buffer.BlockCopy(rBytes, 0, rsBytes, maxSize - rBytes.Length, rBytes.Length);     
Buffer.BlockCopy(sBytes, 0, rsBytes, 2 * maxSize - sBytes.Length, sBytes.Length); 
Console.WriteLine(Hex.ToHexString(rsBytes)); // 00684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

输出为2×maxSize字节,本例中:

00684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

maxSize个字节是r,后maxSize个字节是s.

比较:ASN中的相同签名.1/DER格式为:

3044021f684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5022100849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

Edit:

OP指出,BouncyCastle已经有了这种转换的实现.事实确实如此:

using Org.BouncyCastle.Crypto.Signers;

// Applied curve: secp256r1 aka P-256 aka prime256v1   
BigInteger n = new BigInteger(1, Convert.FromHexString("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")); // n: order of generator point
                                                        
byte[] p1363 = PlainDsaEncoding.Instance.Encode(n, r, s);
Console.WriteLine(Hex.ToHexString(p1363)); // 00684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

byte[] asn1Der = StandardDsaEncoding.Instance.Encode(n, r, s);
Console.WriteLine(Hex.ToHexString(asn1Der)); // 3044021f684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5022100849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

Encode()种方法从生成器点的阶数n确定最大大小.

Csharp相关问答推荐

FromServices不使用WebAppliationFactory程序>

Unity如何在PlayerPrefs中保存数据?

什么是通过反射创建类的泛型接口方法的正确方法?

使用LINQ to XML获取元素值列表是不起作用的

为什么在ANTLR4中会出现不匹配的输入错误?""

. net依赖注入如何避免服务类中的新

如何将Kafka消息时间戳转换为C#中的日期和时间格式?

有没有办法使.NET 6应用程序在特定的.NET 6运行时版本上运行

C#EF Core WHERE IN LINQ FROM LIST WITH.CONTAINS不返回任何内容

使用可信第三方的Iext8.Net pdf签名

如何在用户在线时限制令牌生成?

Linux Docker上的.NET6在某个时间抛出后,在加密操作期间发生System.Security.Cryptography.CryptographicException:错误

如何让两个.NET版本不兼容的项目对话?

为什么此名称不再被识别?名称不存在于当前上下文中?

EF Core 7-忽略模型绑定中的虚拟属性

使用Blazor WebAssembly提高初始页面加载时间的性能

为什么Visual Studio 2022建议IDE0251将我的方法设置为只读?

为什么我的UserControl没有加载到我的主窗口中?

如何在JSON:API中定义的&过滤查询参数系列&标准的GET请求中传递多个相关参数?

将带有嵌套If-Else的Foreach循环转换为Linq表达式