Экспорт открытого ключа в base64 в Ruby

У меня есть открытый ключ в формате 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 в заголовок Crypto-Key в виде строки в кодировке base64 url ​​с добавлением p256ecdsa=.

3 ответа

Решение

Строка PEM на самом деле кодируется в формате base 64 (по крайней мере, частично), но я не думаю, что это то, что вам нужно, она включает в себя другие детали, и я думаю, что вам нужны "сырые" данные открытого ключа.

Вот один из способов получить ключ в формате, который, я думаю, вы хотите. Это немного затянуто, но я не думаю, что привязки OpenSSL в Ruby предоставляют более прямой метод (вам нужно 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 в правильном формате, и преобразует это в двоичную строку. Наконец, эта строка кодируется в base 64.

Извините, что это немного поздно.

Я не очень хорошо знаком с Ruby, поэтому не могу предложить примеры кода для того, что делать, но я могу попытаться описать процесс VAPID. (Кроме того, мои извинения, если я буду вдаваться в ненужные подробности, так как я полагаю, что другие могут наткнуться на это.)

Короче говоря, VAPID - это веб-токен Javascript ( JWT). Вы создаете пару ключей ECDSA, используя свой любимый метод генерации ECDSA специально для VAPID.

например

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://tools.ietf.org/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

У меня смешанное мнение по этому поводу. Это уменьшает потребность в отдельном заголовке, но также сокращает объем информации, которую вы можете вставить в свои заявки, прежде чем исчерпаете комнату заголовка.

Вы могли бы попробовать

  require 'base64'
  Base64.encode64(ecdsa_public_key)

конвертировать в base64

Другие вопросы по тегам