【问题标题】:Generate the VAPID public key in Rails and pass it to Javascript在 Rails 中生成 VAPID 公钥并将其传递给 Javascript
【发布时间】:2017-02-06 23:31:17
【问题描述】:

为了将 Push API 与 VAPID 一起使用,我需要一个 applicationServerKey

serviceWorkerRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey // we've got it with getApplicationServerKey() defined below
});

我用 Ruby 在服务器端生成它:

ecdsa_private_key = OpenSSL::PKey::EC.new 'prime256v1'
ecdsa_private_key.generate_key
sender.vapid_private_key = ecdsa_private_key.to_pem

ecdsa_public_key = OpenSSL::PKey::EC.new ecdsa_private_key
ecdsa_public_key.private_key = nil
sender.vapid_public_key = ecdsa_public_key.to_pem

那我得下载了:

getApplicationServerKey: function () {
  return new Promise(function (resolve, reject) {
    var request = new Request('https://example.com/application_server_key');
    fetch(request).then(function (response) {
      response.text().then(function (base64) {
        resolve(_.base64ToArrayBuffer(base64));
      });
    });
  });
},
base64ToArrayBuffer: function (base64) {
  var binary_string = window.atob(base64);
  var len = binary_string.length;
  var bytes = new Uint8Array(len);
  for (var i = 0; i < len; i++) {
      bytes[i] = binary_string.charCodeAt(i);
  }
  return bytes.buffer;
}

密钥作为 base64 字符串从控制器返回:

ecdsa_public_key = OpenSSL::PKey.read @sender.vapid_public_key
base64 = Base64.encode64(ecdsa_public_key.public_key.to_bn.to_s(2))
render text: base64

问题是当我调用pushManager.subscribe时Firefox返回这个错误:

DOMException [InvalidAccessError: "Invalid raw ECDSA P-256 public key."
code: 15
nsresult: 0x8053000f]

感谢任何帮助。

更新:这让我发疯......我也尝试过使用十六进制而不是 base64 进行编码/解码,但我得到了同样的错误。

来自鲁比:

$ ecdsa_public_key.to_text
=> "Private-Key: (256 bit)\npub: \n
04:28:a9:89:be:8a:a8:f2:f1:bf:ed:04:d2:28:e9:\n
70:e9:b7:f3:8c:3c:f7:20:dc:95:30:1a:72:77:66:\n
09:0d:29:f6:6c:6c:c8:45:6e:da:ac:05:d6:ff:43:\n
9a:66:d0:c3:4c:bc:4a:0f:a3:ad:e8:23:33:22:40:\n
20:9e:de:14:56\n
ASN1 OID: prime256v1\n
NIST CURVE: P-256\n"

$ ecdsa_public_key.public_key.to_bn.to_s 16
=> "0428A989BE8AA8F2F1BFED04D228E970E9B7F38C3CF720DC95301A727766090D29F66C6CC8456EDAAC05D6FF439A66D0C34CBC4A0FA3ADE823332240209EDE1456"

如您所见,它是一个 P-256 密钥(我不知道为什么它说 Private-Key 而不是 Public Key,但是,正如您从生成它的代码中看到的那样,它是一个公钥) .

然后我用 Javascript fetch 下载十六进制字符串,这就是我得到的:

0428A989BE8AA8F2F1BFED04D228E970E9B7F38C3CF720DC95301A727766090D29F66C6CC8456EDAAC05D6FF439A66D0C34CBC4A0FA3ADE823332240209EDE1456

Array [ "04", "28", "A9", "89", "BE", "8A", "A8", "F2", "F1", "BF", 55 more… ]

Uint8Array [ 4, 40, 169, 137, 190, 138, 168, 242, 241, 191, 55 more… ]

ArrayBuffer { byteLength: 65 } // I get it by calling .buffer on the Uint8Array

DOMException [InvalidAccessError: "Invalid raw ECDSA P-256 public key."
code: 15
nsresult: 0x8053000f]

从我在控制台中打印的中间步骤可以看出,密钥已正确处理。但是我仍然收到该错误...

更新 2:相同的代码在 Chrome 中成功运行:我设法使用 VAPID 发送通知。这可能是 Firefox 的错误。

【问题讨论】:

    标签: javascript ruby-on-rails firefox web-push vapid


    【解决方案1】:

    我通过删除.buffer 解决了。

    现在我将Uint8Array 直接传递给subscribe(而不是array.buffer),它适用于Chrome 和Firefox。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-25
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      相关资源
      最近更新 更多