如何在确定性ECDSA-充气城堡上应用P1363格式?

发布于 2025-02-01 22:39:53 字数 3190 浏览 4 评论 0原文

我找不到任何具有 p1363格式的确定性的参考。 rs在确定性模式下始终不同。

非确定性 p1363-> withplain-ecdsa ok

        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

确定性方式 :(如何将与plain-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 s ).toArray()。无法将rs转换为byte []取消转换为p1363?上面的确定性版本中不存在哪个...

  1. 如何以p1363格式串联r r s ?
  2. 如何确保我可以通过将一半的数组转换为r,而另一半则将其转换为s
  3. 有时r等于ss大于r,如何确保生成时确切的两者是相等的?

我找不到P1363的任何参考。 But I found only

    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();
        }

am也尝试了此 但是我循环1000,然后检查r.length == s.length的数组是否循环。 。

不确定是否确切100%,如果盖伊的窍门工作,但是那个家伙试图以固定的方式生成它:

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

简短答案:

根据@topaco的答案,它的快速手动方法。非常感谢他。调查后我们还可以使用两个类,standarddsaencodingplainDSAENCODING classe

  1. standarddsaencododing 用于编码/DECODE ASN1.DER格式。
  2. plaindsaencoding用于编码/解码P1363格式。

plaindsaencoding.instance.encode() //此转换为p1363格式。 plaindsaencoding.instance.decode() //再次解码为biginteger []。 (r,s)

注意:ecdsasigner可以包裹在dsadigestSigner内,以自动允许消息范围。或手动计算哈希(消息),然后使用ecdsAsigner完全像 @topaco其他帖子答案

I don't find any reference for deterministic with P1363 format. the r and s always different in deterministic mode.

Non-Deterministic with P1363 -> WithPlain-ECDSA OK

        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: (How to apply 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.

I can't return r.Concat(s).ToArray(). There's no way to convert r and s to byte[] untill it converted to P1363? which doesn't exist in deterministic version above...

  1. How to concatenate r and s in byte[] in P1363 format?
  2. How to make sure I can convert it back through take half of array for r and other half for s.
  3. Sometimes r equal s, or s larger than r, How to make sure exactly both are equal when generated?

I don't find any reference for P1363. But I found only 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();
        }

Am also tried this trick
But I looped 1000 and check if arrays of r.Length == s.Length, No equality in all loop.. As he use BigInteger.ToByteArrayUnsigned().

Not sure exactly 100% if above guy's trick work, But the guy try to generate it in fixed way:

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

Short Answer:

According to @Topaco answer, its fast manual approach. Many thanks to him. There's also two classes we can use after investigation StandardDsaEncoding and PlainDsaEncoding classes

  1. StandardDsaEncoding used to encode/decode ASN1.Der format.
  2. PlainDsaEncoding used to encode/decode P1363 format.

PlainDsaEncoding.Instance.Encode() // This convert to P1363 format.
PlainDsaEncoding.Instance.Decode() // Decode to signature BigInteger[] again. (r, s)

Note: ECDsaSigner can wrapped inside DsaDigestSigner to allow hash of message automatically. or compute hash(message) manually then use ECDsaSigner exactly like @Topaco other post answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

避讳 2025-02-08 22:39:53

对于P1363,确定性或非确定性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 bytes大,为此示例:

00684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

第一个maxsize字节为r,最后一个maxsize字节为s。

为了进行比较:ASN.1/der格式中相同的签名是:

3044021f684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5022100849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

编辑:

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顺序确定最大大小。

For P1363 it's irrelevant whether the deterministic or non-deterministic ECDSA algorithm is used to determine the signature.

In P1363:

  • r and s are contained as unsigned, big endian arrays
  • r and s are padded to their maximum size (length of the order of the generator point) with leading 0x00 values

In your code, r (toto[0]) and s (toto[1]) are both of type Org.BouncyCastle.Math.BigInteger. The conversion to P1363 is then simply possible with (for simplicity, the maximum size is not calculated, but passed):

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

The output is 2 * maxSize bytes large and for this example:

00684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

The first maxSize bytes are r, the last maxSize bytes are s.

For comparison: The same signature in ASN.1/DER format is:

3044021f684c148ab8582b55fa0929de7853503a05f57119d80cb8b0172103eca369d5022100849be52463b4911ab97c4cbb17322afc0be9a973269d9d263e23bdd43f18426e

Edit:

The OP pointed out that BouncyCastle already has implementations for this conversion. This is indeed the case:

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

The Encode() methods determine the maximum size from the order n of the generator point.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文