Как я могу асимметрично зашифровать данные, используя OpenPGP с Ruby?

Кажется, что это должно быть очень просто, но мне не повезло.

Сценарий таков: у меня есть открытый файл ключа *.asc. Я хочу использовать этот файл (не мой личный набор ключей) для шифрования данных на сервере, чтобы я мог расшифровать их локально с помощью секретного ключа.

Из командной строки я могу добиться этого с помощью gpg, но я бы предпочел использовать библиотеку Ruby, которая не является просто оболочкой для CLI (т. е., предположительно, той, которая обеспечивает привязки к библиотеке C). Я просмотрел драгоценные камни GPGME и OpenPGP и не смог понять, как их использовать. Документация (особенно для OpenPGP) довольно скудна.

Вот, например, то, что я безуспешно пытался использовать с помощью GPGME:

key = GPGME::Data.new(File.open(path_to_file))
data = GPGME::Data.new("I want to encrypt this string.")

# Raises GPGME::Error::InvalidValue
GPGME::Ctx.new do |ctx|
  e = ctx.encrypt(key, data)
end

Кто-нибудь уже проходил через это? Неужели это не может быть так сложно?


person Dan Tao    schedule 18.07.2012    source источник
comment
Я не знаком с GPGME, но сработает ли он, если попробовать GPGME::Key.import(File.open(path_to_file))? Если это все еще не удается, что, если вы декодируете .asc с помощью Base64 и повторяете попытку?   -  person emboss    schedule 18.07.2012
comment
Можете ли вы продемонстрировать, как бы вы сделали это из командной строки? Типичное использование требует, чтобы открытый ключ получателя был сначала импортирован в связку ключей...   -  person PinnyM    schedule 18.07.2012


Ответы (1)


Я полагаю, что теперь понял это. На самом деле мне не хватало нескольких простых частей:

  1. Инициализация объекта GPGME::Ctx с keylist_mode из GPGME::KEYLIST_MODE_EXTERN.
  2. Импорт файла открытого ключа с помощью GPGME::Ctx#import.
  3. Использование GPGME::Crypto#encrypt для выполнения шифрования и указание правильного получателя.

Итак, мое решение теперь выглядит так:

key = GPGME::Data.new(File.open(path_to_file))
data = GPGME::Data.new("I want to encrypt this string.")

GPGME::Ctx.new(GPGME::KEYLIST_MODE_EXTERN) do |ctx|
  ctx.import(key)
  crypto = GPGME::Crypto.new(:armor => true, :always_trust => true)
  e = crypto.encrypt(data, :recipients => "[email protected]")
end
person Dan Tao    schedule 18.07.2012