javascript - Javascript 上的 ECDSA 签名验证失败(椭圆)
问题描述
我在验证 javacard 上的 ECDSA 签名时遇到问题。我正在尝试验证 Javascript(Elliptic) 中的签名,但验证总是失败。
我的小程序(javacard)看起来像:
//initialization
ecdsa = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false);
eccKey=SecP256k1.newKeyPair(); //in SecP256k1 the p,a,b,g,r,k are set
eccKey.genKeyPair();
//singing method
ecdsa.init(eccKey.getPrivate(), Signature.MODE_SIGN);
//Generates the signature of all input data.
short lenTmp = ecdsa.sign(buffer, ISO7816.OFFSET_CDATA, (short)1, buffer,
(short)0);
//I tried also to sigh precomputed hash - same result
/*short lenTmp = ecdsa.signPreComputedHash(buffer, ISO7816.OFFSET_CDATA,
len, buffer, (short)0); */
apdu.setOutgoingAndSend((short)0, lenTmp);
我得到一个私钥
(e.g. : 3E05E289911E66A8153EE9C15A0AFC109C49207DB9DC4656CC4D092323EA65BC)
当我签署消息时(e.g : 0x01)
我得到 DER 格式的签名:
304402205F376BB2B2D48BBB0275099C3B9591F18ECA424DD953EB27FDE37BA819B98F980220539A85B91491E977F6B31B5A76BEF6805BBC3B6481A51C23B9E7C6F39FB70569
它在javacard上的验证也是成功的。但是当我尝试在nodejs上验证它时,它总是失败。我的代码如下所示:
let elliptic = require('elliptic');
let ec = new elliptic.ec('secp256k1');
let keyPair = ec.keyFromPrivate("3E05E289911E66A8153EE9C15A0AFC109C49207DB9DC4656CC4D092323EA65BC");
let privKey = keyPair.getPrivate("hex");
let pubKey = keyPair.getPublic();
let signature = "304402205F376BB2B2D48BBB0275099C3B9591F18ECA424DD953EB27FDE37BA819B98F980220539A85B91491E977F6B31B5A76BEF6805BBC3B6481A51C23B9E7C6F39FB70569";
let msg = 0x01;
let validSig = ec.verify(msg, signature, pubKey);
console.log("Signature valid?", validSig);//returns always false
另外,如果我在 nodejs 上使用相同的密钥签署相同的消息,则验证成功。
此外,我注意到javacard中的签名总是不同的,而椭圆上的签名总是相同的,也许它总是选择相同的随机k。
解决方案
推荐阅读
- android - Cloud Firestore:添加或更新数组
- apache-spark - 使用 python 在 Spark 数据帧中循环
- javascript - 如何单击一个在表格中显示 2 个特定列的复选框
- go - 在 golang 中获取帖子请求失败
- firebase - 如何使用 Kotlin 在 Firebase 中检查孩子的用户名 * 和 * 密码?
- c++ - 动态改变/选择类成员变量的类型
- mysql - Mysql Join 查询需要很长时间或挂起服务器
- r - R - 如何将年龄值分类到年龄组
- reactjs - 如何将反应上下文 API 与 getDerivedStateFromProps 一起使用?
- node.js - 用于 ejs 的 Google 索引