首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有ECDSA验证问题的jsrsa符号

带有ECDSA验证问题的jsrsa符号
EN

Stack Overflow用户
提问于 2022-01-02 17:51:29
回答 1查看 238关注 0票数 0

我可以使用Javascript (window.crypto.subtle.verify)的标准库验证ECDSA /window.crypto.subtle.verify签名,但不能使用jsrsasign (KJUR.crypto)。我也曾直接尝试过“KJUR.crypto.ECDSA”课程,但也没有运气。

请参见下面这两个脚本方法,它们提供的结果不一样。有人能告诉我这个问题吗?

代码语言:javascript
运行
复制
    //function to convert HEX to Decimal - return Arraybuffer
    function hexStringToUint8Array(hexString) {
        if (hexString.length % 2 != 0)
            throw "Invalid hexString";
        var arrayBuffer = new Uint8Array(hexString.length / 2);

        for (var i = 0; i < hexString.length; i += 2) {
            var byteValue = parseInt(hexString.substr(i, 2), 16);
            if (byteValue == NaN)
                throw "Invalid hexString";
            arrayBuffer[i / 2] = byteValue;
        }

        return arrayBuffer;
    }

    //function to convert Base64 to hex (8 bits formats)
    function base64ToHex(str) {
      const raw = atob(str);
      let result = '';
      for (let i = 0; i < raw.length; i++) {
        const hex = raw.charCodeAt(i).toString(16);
        result += (hex.length === 2 ? hex : '0' + hex);
      }
      return result;
    }

    //convert Base64 URL to Base64
    function base64urlToBase64(base64url) {
        base64url = base64url.toString();
        return base64url
            .replace(/\-/g, "+")
            .replace(/_/g, "/");
    }


    //Define values
    Base64URL_coordX = '2uYQAsY-bvzz7r7SL-tK2C0eySfYEf1blv91cnd_1G4';
    Base64URL_coordY = 'S3j1vy2sbkExAYXumb3w1HMVH-4ztoHclVTwQd45Reg';
    signature = 'ed0c2b2e56731511ce2cea1d7320cdbc39dbabca7f525ec5d646b7c11cb35d5846a1cb70c2a1d8480f5ef88b46d401ca78b18ccae9ae4e3934a6b8fe412f7b11';
    dataHex = '48656c6c6f20386777696669';  // ='Hello 8gwifi'


    ////////////Verifying Method using standard javascript
    var dataToVerify = hexStringToUint8Array(dataHex);
    var SignatureToVerify = hexStringToUint8Array(signature);

    window.crypto.subtle.importKey(
        "jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
        {   //this is an example jwk key, other key types are Uint8Array objects
            kty: "EC",
            crv: "P-256",
            x: Base64URL_coordX, // expects  x and y to be «base64url» encoded
            y: Base64URL_coordY,
            ext: true,
        },
        {   //these are the algorithm options
            name: "ECDSA",
            namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
        },
        false, //whether the key is extractable (i.e. can be used in exportKey)
        ["verify"] //"verify" for public key import, "sign" for private key imports
    )
    .then(function(publicKey){
            window.crypto.subtle.verify(
                {
                    name: "ECDSA",
                    hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
                },
                publicKey, //from generateKey or importKey above
                SignatureToVerify,  //ArrayBuffer of the signature
                dataToVerify //ArrayBuffer of the data
            )
            .then(function(isvalid){
                console.log('Signature valid1: ', isvalid);
            })
            .catch(function(err){
                console.error(err);
            });
    });


    ////////////Verifying Method using KJUR
    Hex_coordX = base64ToHex(base64urlToBase64(Base64URL_coordX));
    Hex_coordY = base64ToHex(base64urlToBase64(Base64URL_coordY));
    var XY = Hex_coordX.toString(16) + Hex_coordY.toString(16);

    var sig = new KJUR.crypto.Signature({"alg": "SHA256withECDSA", "prov": "cryptojs/jsrsa"});
    sig.init({xy: XY, curve: "secp256r1"});
    sig.updateHex(dataHex);
    var result = sig.verify(signature);

    //Printing Verification
    console.log('Signature valid2: ', result);
EN

回答 1

Stack Overflow用户

发布于 2022-01-02 21:05:37

它在对库的描述中说它是JCA风格。这可能意味着签名生成/验证功能具有ASN.1 / DER编码输入/输出。

这包括一个ASN.1序列(标签0x30),即内部两个整数的长度。这两个整数的有标签0x02和签名的r和s组件的整数值的长度。这些是大数,有符号整数(这意味着如果字节为0x00,则剥离字节;如果顶部字节为0x80或更高,则添加0x00 )。

就你而言,这将是:

代码语言:javascript
运行
复制
r = ed0c2b2e56731511ce2cea1d7320cdbc39dbabca7f525ec5d646b7c11cb35d58
s = 46a1cb70c2a1d8480f5ef88b46d401ca78b18ccae9ae4e3934a6b8fe412f7b11

现在将这些转换为ASN.1:

代码语言:javascript
运行
复制
ri = 02 21  00 ed0c2b2e56731511ce2cea1d7320cdbc39dbabca7f525ec5d646b7c11cb35d58
si = 02 20 46a1cb70c2a1d8480f5ef88b46d401ca78b18ccae9ae4e3934a6b8fe412f7b11

最后,添加该序列并添加上述的级联:

代码语言:javascript
运行
复制
sig = 30 45 02 21  00 ed0c2b2e56731511ce2cea1d7320cdbc39dbabca7f525ec5d646b7c11cb35d58
02 20 46a1cb70c2a1d8480f5ef88b46d401ca78b18ccae9ae4e3934a6b8fe412f7b11

检查结果,例如这里

但我想在你的情况下,打电话给concatSigToASN1Sig会更快:P

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70558358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档