ASN1ECDSA签名值与[R,S]签名值转换

ASN1ECDSA签名值与[R,S]签名值转换
256位椭圆曲线的ECDSA签名的结构为:
10x30(48)
2签名字节长度-2([4]+[7+[4]]+4)
4⼤数R字节长度
5~5+[4]⼤数R(最⾼位为1则添加⼀个字节0在最⾼位前)
6+[4]0x02(2)
7+[4]⼤数S字节长度
7+[4]+[7+[4]]⼤数S(最⾼位为1则添加⼀个字节0在最⾼位前)
正常⽣成的⼤数R、S均为32字节或33字节,但在测试过程中发现,存在⼀定概率(约4‰)第4或第7+[4]字节(即R或S的字节长度)为31,推测是由于⽣成的⼤数最⾼字节(包括符号位)为全为0,故在签名值中省略⾼位0,不难计算,随机⽣成的两个⼤数R和S中⾄少⼀个前9位均为0的概率为0.5^9+0.5^9-0.5^18≈3.9‰,符合实际。
附256位ECDSA与RS转换代码:
byte[] asn1ECDSAToRS(byte[] signature) {
byte[] rs = new byte[64];
int rsLen = signature[1] & 0xff;
int rLen = signature[3] & 0xff;
int sLen = rsLen - rLen - 4;
System.arraycopy(signature, rLen == 33 ? 5 : 4, rs, rLen == 31 ? 1 : 0, rLen == 31 ? 31 : 32);
System.arraycopy(signature, sLen == 33 ? rLen + 7 : rLen + 6, rs, sLen == 31 ? 33 : 32, sLen == 31 ? 31 : 32);
return rs;
}
byte[] rsToASN1ECDSA(byte[] rs) {
int p = 0, rLen = rs[0] < 0 ? 33 : (rs[0] > 0 ? 32 : 31), sLen = rs[32] < 0 ? 33 : (rs[32] > 0 ? 32 : 31);
byte[] signature = new byte[rLen + sLen + 6];
signature[p++] = 48;
signature[p++] = (byte) (rLen + sLen + 4);
signature[p++] = 2;
signature[p++] = (byte) rLen;
System.arraycopy(rs, rLen == 31 ? 1 : 0, signature, p + (rLen == 33 ? 1 : 0), rLen == 31 ? 31 : 32);
p += rLen;
signature[p++] = 2;
signature[p++] = (byte) sLen;
System.arraycopy(rs, sLen == 31 ? 33 : 32, signature, p + (sLen == 33 ? 1 : 0), sLen == 31 ? 31 : 32);
return signature;
}
可能出现转换前后签名值不⼀致的问题,但均可正常验签,不⼀致问题的原因是由于部分最⾼位全为0的⼤数R或S的最⾼位并未被省略,具体原因不明,但去掉⾼位0后可正常验签。

本文发布于:2024-09-24 04:23:07,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/368542.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:字节   签名   原因
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议