简体   繁体   English

从 Firefox 中的 PEM 导入椭圆曲线私钥

[英]Import elliptic curve private key from PEM in Firefox

I am trying to import an elliptic curve private key from PEM encoding.我正在尝试从 PEM 编码中导入椭圆曲线私钥。 The following code works fine on Chrome but does not work with Firefox.以下代码在 Chrome 上运行良好,但不适用于 Firefox。 It says:它说:

ERR Operation is not supported

Browsing around I've got impression it is a know problem, however I did not find a solution.浏览我的印象是这是一个已知问题,但是我没有找到解决方案。 Is there any workaround to import ECDSA private key from PEM on Firefox?是否有任何解决方法可以从 Firefox 上的 PEM 导入 ECDSA 私钥? In preference I want a solution working with reasonably older versions of Firefoxes.优先考虑,我想要一个适用于相当旧版本的 Firefox 的解决方案。

<html>
    <body>
        <script>
         function stringToArrayBuffer(str) {
             var buf = new ArrayBuffer(str.length);
             var bufView = new Uint8Array(buf);
             var len = str.length;
             for (var i=0; i<len; i++) {
                 bufView[i] = str.charCodeAt(i);
             }
             return buf;
         };
         function importPrivateKey(pem) {
             // console.log("PP", pem);
             var crypto = window.crypto || window.msCrypto;
             // fetch the part of the PEM string between header and footer
             const pemHeader = "-----BEGIN PRIVATE KEY-----";
             const pemFooter = "-----END PRIVATE KEY-----";
             const pemContents = pem.substring(pemHeader.length+1, pem.length - pemFooter.length - 2);
             // base64 decode the string to get the binary data
             const binaryDerString = window.atob(pemContents);
             // convert from a binary string to an ArrayBuffer
             const binaryDer = stringToArrayBuffer(binaryDerString);
             var res = crypto.subtle.importKey("pkcs8", binaryDer, {name: "ECDSA", namedCurve: "P-384"}, true, ["sign"]);
             return(res);
         }
         var promise_key = importPrivateKey("-----BEGIN PRIVATE KEY-----\nMIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBmb0Yu9UxnUhKN0Cwf\nq/OWVzNTdPKBsUHsVXJAKVUYczDQ7+PYnFxyoVaz8PtoGuihZANiAAQc7WOnfjtL\njDV0+anLxnG2d0p2d7PkdwQBLTu5nONzwOLG0fqeEzbrPRQ125PHQxz7Qr2S4/xz\nC4OVDzebpD/ABnN+QRuiUXf2SMtz90xs80sMLS3glv7OMLCTQLz3P/o=\n-----END PRIVATE KEY-----\n");
         promise_key.then(
             function(key){
                 console.log("OK");
             },
             function(e){
                 console.log("ERR", e.message);
             }      
         );
        </script>
    </body>
</html>

I am answering my own question for case someone find it useful.我正在回答我自己的问题,以防有人觉得它有用。 As suggested by Michael a possible workaround is to use "jsrsasign" library and KEYUTIL functions.正如 Michael 所建议的,一种可能的解决方法是使用“jsrsasign”库和 KEYUTIL 函数。 After having installed jsrsasign, the following code imports ECDSA private key on both Chrome and Firefox.安装 jsrsasign 后,以下代码在 Chrome 和 Firefox 上导入 ECDSA 私钥。

<html>
    <head>
    </head>
    <body>
        <script type='text/javascript' src='jsrsasign-master/jsrsasign-all-min.js'></script>
        <script>
         function importPrivateKey(pem) {
             var jsrasignkey = KEYUTIL.getKeyFromPlainPrivatePKCS8PEM(pem);
             var jwkkey = KEYUTIL.getJWKFromKey(jsrasignkey);
             var res = crypto.subtle.importKey("jwk", jwkkey, {name: "ECDSA", namedCurve: "P-384"}, true, ["sign"]);
             return(res);
         }
         var promise_key = importPrivateKey("-----BEGIN PRIVATE KEY-----\nMIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBmb0Yu9UxnUhKN0Cwf\nq/OWVzNTdPKBsUHsVXJAKVUYczDQ7+PYnFxyoVaz8PtoGuihZANiAAQc7WOnfjtL\njDV0+anLxnG2d0p2d7PkdwQBLTu5nONzwOLG0fqeEzbrPRQ125PHQxz7Qr2S4/xz\nC4OVDzebpD/ABnN+QRuiUXf2SMtz90xs80sMLS3glv7OMLCTQLz3P/o=\n-----END PRIVATE KEY-----\n");
         promise_key.then(
             function(key){
                 console.log("OK");
             },
             function(e){
                 console.log("ERR", e.message);
             }      
         );
        </script>
    </body>
</html>

Unfortunately, it is a long-lasting and still open bug in the WebCrypto engine of Firefox (see bugzilla.mozilla.org/show_bug.cgi?id=1133698).不幸的是,它是 Firefox 的 WebCrypto 引擎中一个长期存在且仍然存在的错误(参见 bugzilla.mozilla.org/show_bug.cgi?id=1133698)。

Up to now there are three solutions:到目前为止,解决方案有以下三种:

  • First: don't use Firefox but eg Chrome or Opera.首先:不要使用 Firefox,而是使用 Chrome 或 Opera。
  • Second: Use keys in the RAW or JWK encoding.第二:使用 RAW 或 JWK 编码的密钥。
  • Third: write an PEM to JWK converter.第三:写一个PEM到JWK的转换器。

Yes, I know, all three options don't make me happy either.是的,我知道,这三个选项也不会让我高兴。

Maybe you could use JSRSASIGN (npmjs.com/package/jsrsasign) - it supports ECDSA as well?也许您可以使用JSRSASIGN (npmjs.com/package/jsrsasign) - 它也支持 ECDSA?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM