0

我有一个 PEM 格式的公钥,它是通过以下方式生成的:

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

我必须阅读 PEM 字符串并获得base64 url​​ 编码的字符串。我怎样才能在 Ruby 中做到这一点?

ecdsa_public_key = OpenSSL::PKey.read pem_string
ecdsa_public_key.to_base64 # pseudo code...

顺便说一句,我必须为 WebPush 协议执行此操作,该协议指出:

您必须将您的 VAPID 公钥作为 base64 url​​ 编码的字符串添加到 Crypto-Key 标头,并在其前面加上 p256ecdsa=。

4

3 回答 3

4

PEM 字符串实际上是 base 64 编码(至少部分),但我认为这不是您想要的,它包含其他细节,我认为您想要“原始”公钥数据。

这是您将密钥转换为我认为您想要的格式的一种方法。这有点啰嗦,但我不认为 Ruby 的 OpenSSL 绑定提供了更直接的方法(您需要require "base64"首先):

# Assuming the key is in ecdsa_public_key
Base64.urlsafe_encode64(ecdsa_public_key.public_key.to_bn.to_s(2), padding: false)

这调用public_key获取底层OpenSSL::PKey::EC::Point,然后将其转换OpenSSL::BN为正确格式的,并将其转换为二进制字符串。最后这个字符串是base64编码的。

于 2017-02-06T16:19:51.510 回答
0

抱歉,这有点晚了。

我对 Ruby 不是很熟悉,所以我无法提供代码示例来说明要做什么,但我可以尝试描述一下 VAPID 的过程。(另外,如果我进入不必要的细节,我深表歉意,因为我认为其他人可能会偶然发现这一点。)

简而言之,VAPID 是一种 Javascript Web 令牌 ( JWT )。您可以使用您最喜欢的专门针对 VAPID 的 ECDSA 生成方法创建一个 ECDSA 密钥对。

例如

openssl ecparam -name prime256v1 -genkey -noout -out vapid_private.pem
openssl ec -in vapid_private.pem -pubout -out vapid_public.pem

“PEM”是一个格式化文件,包括一个标准的标题行、一个页脚行和一组长长的废话字符串。(不确定这是否是他们的技术术语,但是是的,我将继续使用。)那些长长的废话字符串是以特定格式保存的关键数据的 Base64 表示。

老实说,我强烈鼓励在可能的情况下使用图书馆。jwt.io 有许多您可以使用的 Ruby 库,以及其他语言的库。至于“Crypto-Key:”标题,有一些好消息/其他消息。

  1. 您可以从您的 vapid-public.pem 文件中获取长长的废话字符串,将它们附加在一起并将它们指定为 'p256ecdsa=' 键。
  2. VAPID 协议即将更改https://datatracker.ietf.org/doc/html/draft-ietf-webpush-vapid-02

该更改有效地摆脱了 Crypto-Key p256ecdsa 组件。相反,授权密钥变为:

授权: vapid t= JWT 包含 VAPID 信息,k= VAPID 公钥

例如

vapid t=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtYWlsdG86d2VicHVzaF9vcHNAY2F0ZmFjdHMuZXhhbXBsZS5jb20iLCJleHAiOjE0ODc0NDM3MTR9.mlLOWYMt-6aM3NB6b6_Msf8LqRKCuHd1Vfdp_fuJ3eqsQoID8lit305hIfNubTbvfACucuCygF3qB4scDbuHvg,k=EJwJZq_GN8jJbo1GGpyU70hmP2hbWAUpQFKDByKB81yldJ9GTklBM5xqEwuPM7VuQcyiLDhvovthPIXx-gsQRQ

我对此持不同意见。它确实减少了对单独标题的需求,但也缩短了您在标题空间用完之前可以塞入索赔中的信息量。

于 2017-02-17T18:53:06.910 回答
-1

你可以试试

  require 'base64'
  Base64.encode64(ecdsa_public_key)

转换为base64

于 2017-02-06T14:51:41.620 回答