当前位置: 首页 > 知识库问答 >
问题:

UWP ECDSP签名

白星海
2023-03-14

我想用这段代码制作一个ECDSA签名:

AsymmetricKeyAlgorithmProvider objAsymmAlgProv = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.EcdsaSha256);
CryptographicKey keypair = objAsymmAlgProv.CreateKeyPairWithCurveName(EccCurveNames.SecP256r1);
BinaryStringEncoding encoding = BinaryStringEncoding.Utf8;
buffMsg = CryptographicBuffer.ConvertStringToBinary("Test Message", encoding);
IBuffer buffSIG = CryptographicEngine.Sign(keypair, buffMsg);
byte [] SignByteArray = buffSIG.ToArray();
bool res = CryptographicEngine.VerifySignature(keypair, buffMsg, buffSIG);

验证签名始终返回true,这是正常的。

但我在签名方面有一些问题。

为什么签名(< code>SignByteArray)的长度是固定的?(0x40字节)。

为什么 SignByteArray [0]SignByteArray [2] 值不正确?(我认为他们应该0x30和0x02)

我期待像https://kjur.github.io/jsrsasign/sample-ecdsa.html一样的东西

共有1个答案

夹谷承安
2023-03-14

ECDSA规范以确定对(rs)是签名结束。它忽略做的是指示应该如何将它们写下来。

Windows和.NET使用IEEE(P)1363格式,即大端r concat big-endian srs 具有相同的大小(由密钥大小决定),因此签名的长度始终是偶数,r 是前半部分。

OpenSSL使用ASN.1/ DER编码,即SERENCY(INTEGER(r),INTEGER(s))。DER 编码可以一直向下延伸到 6 个字节(30 04 02 00 02 00,在退化 r=0 中,s=0),并且平均比 IEEE 形式大 6 个字节。它编码为 30 [长度,一个或多个字节] 02 [长度,一个或多个字节] [可选填充 00] [没有前导 00 的大端 r] 02 [长度,一个或多个字节] [可选填充 00] [没有前导 00 的大端 s]。

DER形式太依赖于数据而无法具体描述,因此示例应该会有所帮助。假设我们在32位字段中使用曲线并生成(r=1016, s=2289644760)。

IEEE 1363:

// r
00 00 03 F8
// s
88 79 34 D8

德:

SEQUENCE(INTEGER(1016), INTEGER(2289644760))

// Encode r
// 1016 => 0x3F8 => 03 F8 (length 02)
SEQUENCE(
    02 02
       03 F8,
    INTEGER(2289644760))

// Encode s
// 2289644760 => 0x887934D8 => 88 79 34 D8
// But since the high bit is set this is a negative number (-2005322536),
// and s is defined to be positive.  So insert a 00 to ensure the high bit is clear.
//   => 00 88 79 34 D8 (length 05)
SEQUENCE(
    02 02
       03 F8
    02 05
       00 88 79 34 D8)

// And encode the sequence, whose payload length we can now count as 11 (0B)
30 0B
   02 02
      03 F8
   02 05
      00 88 79 34 D8

所以Windows/. NET发出00 00 03 F8 88 79 34 D8,而OpenSSL发出300B02 03 F8 02 05 00 88 79 34 D8。但它们都只是说(r, s)=(1016,2289644760)

(题外话:您观察到DER编码中的签名[2] == 0x02对于您正在使用的大小密钥是正确的,但是在大约496位密钥下,SEQUENCE长度在统计上可能需要多个字节;因此对于P-521密钥,它最有可能从03 81 88 02开始,在88字节中具有可变性)

 类似资料:
  • Pushes 签名 git push can be instructed to sign the push. The server may use this to control the execution of certain hooks: git push 可以被指示进行签名 push。服务器可以使用它来控制一些钩子的执行: ❯ git push --signed Github 现在貌似并没有

  • Merges 签名 git merge 命令可以在合并没有使用 --verify-signatures 命令带有不可信 GPG 签名的 commit/branch 时检查和拒绝 如果被合并的分支中有任何没有被有效签名认证的提交,合并将不会继续。 Merge commit 本身也是可以被签名的(使用 -S): ❯ git checkout -b enhancement/foo ❯ touch qux

  • Commits 签名 在上文提到的 git 仓库中添加一个新文件,并使用 -S 标签来提交(commit)它。(注意不是 -s 标签,在 commit 命令下它意味着 Signed-Off): ❯ touch biz ❯ git add biz ❯ git commit -S -m "Add biz" 你可以通过在 ~/.gitconfig.local 文件中添加下列内容来开启 commit 自动

  • Tags 签名 假设你有一个额外的文件可以在主 ~/.gitconfig 中添加 gitconfig 设置: [include] path = .gitconfig.local 配置 ~/.gitconfig.local 文件让其指向你插入的 GPG 签名钥匙: [user] signingkey = <signingKeyId> 开启 git tag -m <message> 来

  • 签名 ConsenSys的Infura服务提供了在云端运行的以太坊客户端的能力,所以你不必自己运行一个独立的以太坊客户端以便与以太坊一起工作。 当你注册这个服务时,你可以提供一个token令牌,你可以使用它连接到相关的以太坊网络: 以太网网络/公有链: https://mainnet.infura.io/<your-token> 以太坊测试网络/测试链(Rinkeby): https://rink

  • 签名算法是使用私钥签名,公钥验证的方法,对一个消息的真伪进行确认。如果一个人持有私钥,他就可以使用私钥对任意的消息进行签名,即通过私钥sk对消息message进行签名,得到signature: signature = sign(message, sk); 签名的目的是为了证明,该消息确实是由持有私钥sk的人发出的,任何其他人都可以对签名进行验证。验证方法是,由私钥持有人公开对应的公钥pk,其他人

  • 前言 随着区块链等相关技术的创新和突破,很多有形或无形资产都将实现去中心化,数字资产将无处不在。比如我们这里分享的 亿书 就是要把数字出版物版权进行保护,实现去中心化,解决业界多年来版权保护不力的难题。 无论数字资产,还是数字出版版权,都是有明确所有权的,当前实现数字资产所属的技术手段就是本篇要介绍的签名。而多重签名是对签名的扩展使用,给数字资产转移提供了安全保障和技术手段。本篇,从基本概念入手,

  • 我想创建一个签名并使用openssl验证它。我想有我的签名的十六进制输出。 这是我的密码 我得到这个错误: 如果我在创建签名的过程中删除了-hex,它就可以工作了。