Using passphrase callback in ruby gpgme

空扰寡人 提交于 2019-11-30 23:31:31

Sample of callback you can find in the following working example. It signs a file in detached mode, i.e., the signature file is separated from the original file. It uses the default keyring at ~/.gnupg or something like that. To use a different directory for your keyring, set the environment variable ENV["GNUPGHOME"]="" before call GPGME::sign().

#!/usr/bin/ruby
require 'rubygems'
require 'gpgme'

puts "Signing #{ARGV[0]}" 
input = File.open(ARGV[0],'r')

PASSWD = "abc"

def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
    puts("Passphrase for #{uid_hint}: ")
    io = IO.for_fd(fd, 'w')
    io.write(PASSWD+"\n")
    io.flush
end

output = File.open(ARGV[0]+'.asc','w')

sign = GPGME::sign(input, {
        :passphrase_callback => method(:passfunc), 
        :mode => GPGME::SIG_MODE_DETACH
    })
output.write(sign)
output.close
input.close

Here's another working example for you that doesn't use a detached signature. To test this, simply change 'user@host.name' to the identifier of your key and do this: GPG.decrypt(GPG.encrypt('some text', :armor => true))

require 'gpgme'
require 'highline/import'

module GPG
  ENCRYPT_KEY = 'user@host.com'
  @gpg = GPGME::Crypto.new

  class << self

    def decrypt(encrypted_data, options = {})
      options = { :passphrase_callback => self.method(:passfunc) }.merge(options)
      @gpg.decrypt(encrypted_data, options).read 
    end

    def encrypt(data_to_encrypt, options = {})
      options = { :passphrase_callback => self.method(:passfunc), :armor => true }.merge(options)
      @gpg.encrypt(data_to_encrypt, options).read
    end

    private
      def get_passphrase
        ask("Enter passphrase for #{ENCRYPT_KEY}: ") { |q| q.echo = '*' }
      end

      def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
        begin
          system('stty -echo')
          io = IO.for_fd(fd, 'w')
          io.puts(get_passphrase)
          io.flush
        ensure
          (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
          system('stty echo')
        end
        $stderr.puts
      end
  end
end

Cheers!,

-- Carl

It is important to note that as of GnuPG 2.0 (and in 1.4 when the use-agent option is used) pinentry is used for passphrase collection. This means that the gpgme passphrase callback will not be invoked. This is described here and an example of usage can be found in the gpgme-tool example.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!