Chrome中的crypto.subtle.importKey会抛出DOMException,而Firefox运行良好

时间:2017-08-24 17:26:15

标签: javascript google-chrome cryptography domexception

我正在尝试导入ECDSA公钥,如下所示:

ua8 = new Uint8Array( [48, 86, 48, 16, 6, 4, 43, 129, 4, 112, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 124, 78, 186, 4, 136, 215, 226, 113, 200, 80, 93, 199, 105, 63, 47, 60, 193, 162, 180, 226, 160, 164, 9, 183, 122, 42, 97, 201, 99, 128, 54, 227, 193, 220, 229, 75, 186, 223, 201, 227, 229, 159, 159, 67, 205, 3, 126, 74, 211, 202, 122, 66, 185, 150, 74, 152, 192, 177, 81, 155, 106, 237, 212, 146] );
crypto.subtle.importKey( "spki", ua8, { name: "ECDSA", namedCurve: "P-256", }, false, ["verify"] );

在Firefox中,这种方法效果很好,但在Chrome中我得到了一个DOMException。

我希望它能在两种浏览器中运行。我该如何解决?

1 个答案:

答案 0 :(得分:1)

根据the Chromium WebCrypto documentation

  

Chromium的WebCrypto实施支持所有关键格式 - " raw"," spki"," pkcs8"," jwk&# 34;,有以下警告:

     
      
  • Web加密实现之间的DER密钥格式处理存在差异。在可能的情况下,使用" raw"键或" jwk"它具有更好的互操作性。

  •   
  • 导入/导出" spki"和" pkcs8"格式,Chromiumare支持的唯一OID,由OpenSSL / BoringSSL识别。

  •   
特别是,它说:

  
      
  • 导入ECDH密钥does not accept id-ecDH。 OID必须改为id-ecPublicKey(这可能导致导入Firefox生成的密钥出现问题;使用" raw" EC密钥作为解决方法;在这种情况下,Chromium不符合规范)
  •   

(错误跟踪器链接给我一个500内部服务器错误,但这可能是暂时的。)

Looking at your key in an ASN.1 decoder,它包含以下数据:

SEQUENCE (2 elem)
    SEQUENCE (2 elem)
        OBJECT IDENTIFIER 1.3.132.112
        OBJECT IDENTIFIER 1.2.840.10045.3.1.7 prime256v1 (ANSI X9.62 named elliptic curve)
    BIT STRING (520 bit) 0000010001111100010011101011101000000100100010001101011111100010011100…

对象标识符1.3.132.112恰好是" id-ecDH" Chrome无法识别的标识符。对于它的价值,a key exported from Chrome而不是OID 1.2.840.10045.2.1(" ecPublicKey")。

正如链接文档页面所示,作为一种解决方法,您可能希望切换到" spki"格式化为" raw" (或"jwk",基于JSON)。