0

嗨,我喜欢从 erlang 服务器应用程序发送 FCM 推送通知。当用户在浏览器中订阅 FCM 通知时。swRegistration.pushManager.subscribe() 需要一个公钥(applicationServerKey)。

所以要获得这个密钥,我使用 openssl 并生成两个 PEM 文件私钥和公钥。

openssl ecparam -name prime256v1 -genkey -noout -out es_private_key.pem   
openssl ec -in es_private_key.pem -pubout -out es_public_key.pem

我知道你可以从 firebase 控制台获取私钥和​​公钥。但是提供的密钥不是 PEM 格式,并且签署 JWT 的 erlang 库使用PEM 文件进行签名和验证。

{ok, PrivtPem} = file:read_file("path/to/es_private_key.pem"),
Jwt = jwerl:sign([{name, <<"bob">>}], es256, PrivtPem).

因此,从生成的私人 PEM 密钥中,我可以对 JWT 进行签名,但我需要 base64 字符串格式的 applicationServerKey 将其添加到标头中,并在浏览器中订阅用户。

我应该将 firebase 控制台中的密钥转换为 PEM 或将 PEMS 转换为 firebase 密钥格式。

我花了两天时间尝试用 Erlang 来做这件事。

我发现如何在 Python 中做到这一点,我需要一些在 erlang 中等效的东西。

raw_pub = vapid.public_key.public_bytes(
                serialization.Encoding.X962,
                serialization.PublicFormat.UncompressedPoint
            )
        print("Application Server Key = {}\n\n".format(
            b64urlencode(raw_pub)))
4

1 回答 1

1

几天后,我找到了如何在 Erlang 中执行此操作。

首先,我使用了一个名为 Vladimir 的名为base64Url的库。

然后我使用了JWERL作者使用的代码,最后我对 ECPoint bin 内容进行了 base64Url 编码。

在erlang代码下面:

pem_to_string()->
{ok, key} = file:read_file("/home/keys/es_public_key.pem"),
 [SPKI] = public_key:pem_decode(Key),
  #'SubjectPublicKeyInfo'{algorithm = Der} = SPKI,
  RealSPKI = public_key:der_decode('SubjectPublicKeyInfo', Der),
  #'SubjectPublicKeyInfo'{
     subjectPublicKey = Octets,
     algorithm = #'AlgorithmIdentifier'{ parameters = Params}
    } = RealSPKI,
  ECPoint = #'ECPoint'{point = Octets}, 
{'ECPoint', Bin} = ECPoint,
base64url:encode(Bin).

我不是加密密钥和弯曲密钥方面的专家,我只想签署推送内容,因为谷歌想要这个。所以这段代码给了我 64 个八位字节 base64 编码的公钥。我可以在推送 FCM 中使用这个公钥。

我希望这对某人有用。

于 2020-10-19T14:56:15.717 回答