Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么同一个HSM密钥每次都验证到不同的以太坊地址?_Javascript_Encryption_Cryptography_Ethereum_Hsm - Fatal编程技术网

Javascript 为什么同一个HSM密钥每次都验证到不同的以太坊地址?

Javascript 为什么同一个HSM密钥每次都验证到不同的以太坊地址?,javascript,encryption,cryptography,ethereum,hsm,Javascript,Encryption,Cryptography,Ethereum,Hsm,我正在与正在生成以太坊标准(secp256k1)并与之签署的HSM进行接口。我用一个叫做石墨烯的包和HSM连接。我使用其“pointEC”属性取出公钥: 0xC87C1D67C1909EBF8B54C9CE3D8E0F0CDE41561C8115481321E45B364A8F3334B6E826363D8E895110FC9CA2D75E84CC7C56B8E9FBCD70C726CB44F506848FA 我可以使用它生成地址:0x21d20b04719f25d2ba0c68e851bb64

我正在与正在生成以太坊标准(secp256k1)并与之签署的HSM进行接口。我用一个叫做石墨烯的包和HSM连接。我使用其“pointEC”属性取出公钥:
0xC87C1D67C1909EBF8B54C9CE3D8E0F0CDE41561C8115481321E45B364A8F3334B6E826363D8E895110FC9CA2D75E84CC7C56B8E9FBCD70C726CB44F506848FA

我可以使用它生成地址:
0x21d20b04719f25d2ba0c68e851bb64fa570a9465

但是,当我尝试使用密钥对来自dApp的个人消息进行签名时,签名总是计算为不同的地址。例如,nonce/消息:
wAMqcOCD2KKz2n0Dfbu1nRYbeLw_qbLxrW1gpTBwkq
具有以下签名:

0x2413f8d2ab4df2f3d87560493f21f0dfd570dc61136c53c236731bf56a9ce02cb23692e6a5cec96c62359f6eb4080d80328a567d14387f487f3c50d9ce61503b1c

但它恢复
0xFC0561D848b0cDE5877068D94a4d803A0a933785的有效地址

这一切大概都使用相同的私钥/公钥。当然,我只是附加了“1c”恢复值,但即使尝试使用其他值,我也没有运气。这里还有几个例子:

Nonce: WRH_ApTkfN7yFAEpbGwU9BiE2M6eKTZMklPYK50djnx
Sig: 0x70242adabfe27c12e54abced8de87b45f511a194609eb27b215b153594b5697b7fb5e7279285663f80c82c2a2f2920916f76fd845cdecb45ace19f76b0622ac41c
Address: 0x1A086eD40FF90E75764260E2Eb42fab4Db519E53

Nonce: TZV6qhplddJgcKaN7qtpcIhudFhiQ
Sig: 0x3607beb3d58ff35ca1059f3ea44f41e79e76d8ffe35a4f716e78030f0fe2ca1da51f138c31d4ec4b9fc3546c4de1185736a4c4c7030a8b1965e30cb0af6ba2ee1c
Address: 0xa61A518cf73163Fd92461942c26C67c203bda379
签署邮件的我的代码:

        let alg: graphene.MechanismType;
        alg = graphene.MechanismEnum.ECDSA;
        const session = get_session();

        let key: graphene.Key | null = null;
        //#region Find signing key
        const objects = session.find({label: GEN_KEY_LABEL});
        for (let i = 0; i < objects.length; i++) {
            const obj = objects.items(i);
            if ((obj.class === graphene.ObjectClass.PRIVATE_KEY ||
                obj.class === graphene.ObjectClass.SECRET_KEY) &&
                obj.handle.toString('hex') == params.handle
            ) {
                key = obj.toType<graphene.Key>();
                break;
            }
        }
        if (!key) {
            throw new Error("Cannot find signing key");
        }
        var sign = session.createSign(alg,key);
        if (!params.data) {
            console.log("No data found. Signing 'test' string");
            params.data = 'test';
        }
        sign.update(Buffer.from(params.data.toString().trim()));
        var signature = sign.final();



        console.log(signature.toString('hex'));
let alg:graphene.MechanismType;
alg=石墨烯.mechanismenu.ECDSA;
const session=get_session();
let key:graphene.key | null=null;
//#区域查找签名密钥
const objects=session.find({label:GEN_KEY_label});
for(设i=0;i

请记住,即使只有一个密钥,它也会失败。

地址只是通过公钥计算的,而签名是使用ECDSA生成的。ECDSA,它由一个随机值r和一个特定于该随机值的签名s(当然还有私钥)组成。更多信息

您看不到这一点,因为它们只是被编码为静态大小(无符号,大整数)的值,然后连接在一起称为“签名”(因此签名的大小是密钥大小的两倍,是64字节,而不是32字节)。验证将解析签名并再次使用单独的值。对于以太坊和比特币,签名前可能会加上一个字节,这样就可以检索回公钥,然后重新计算地址。这也改变了签名生成,因此您不再谈论普通的ECDSA


还有X9.62签名格式,它仍然由两个单独的整数组成,使用ASN.1/DER编码。由于分离/编码两个整数所需的开销,这些签名看起来只是部分随机的。

原来我使用的是一个弃用的Buffer.from函数,因为更新版本要求您指定传入数据的格式

例如缓冲区从(“04021a”、“十六进制”)

由于这是最终的“输入”和计算,我花了很长时间才意识到数据在那个时候被错误地转换了。我以为我在每一步都反复检查了很多次数据,但是错过了你脸上最重要的部分

此外,我还了解到,要创建正确的签名并防止交易的延展性,您必须不断辞职,以便“s”的值最终小于:
(0xfffffffffffffffffffffffebaaedCE6AF48A03BBFD25E8CD0364141)/2


然后,当通过地址恢复函数输入'r'和's'时,它应该尝试用v=27或v=28(0x1a或0x1b)恢复地址,基本上在这一点上是反复试验。大多数情况下,它会用v=27恢复正确的地址。

您可能需要共享用于签名邮件的代码和用于恢复签名者的代码。恢复签名者的代码只是web3的JS库。如果不看到代码,很难说,但是您在使用
web3
时,可能希望先用keccak256对已签名的数据进行散列,然后再加上前缀“\x19Ethereum signed Message:32\n”。您在签名代码中显然没有这样做。正在签名的数据已经是这种格式。所有这些操作都是将其发送给HSM以签名并返回签名。
params.data.toString()的实际值是多少?传递给sign.update
的确切内容是什么?我如何使用公钥生成的地址的正确值进行签名?嗯,我必须查找:|不是区块链专家,只是前几天刚刚查找地址计算方法的加密专家。这可能需要一些时间。请注意,虽然签名不是直接比较的,但您只需验证它们的正确性。我只是不知道如何以签名将验证生成地址的方式进行签名。能否从签名中获取公钥?请参见此处的答案:。请注意第二个答案下面的评论:“事实证明,在我的例子(比特币消息签名)中,他们在签名后附加了一个额外的字节,以确定两点中的哪一点是公钥。完成后,他们计算出一个16