{"id":15048360,"url":"https://github.com/github/ruby-gpgme","last_synced_at":"2025-10-04T08:31:54.910Z","repository":{"id":65974897,"uuid":"157627822","full_name":"github/ruby-gpgme","owner":"github","description":"a ruby interface to GnuPG Made Easy (GPGME).","archived":true,"fork":true,"pushed_at":"2022-10-20T15:39:30.000Z","size":25805,"stargazers_count":8,"open_issues_count":1,"forks_count":10,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-09-30T00:23:17.694Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"ueno/ruby-gpgme","license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/github.png","metadata":{"files":{"readme":"README.rdoc","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-15T00:09:30.000Z","updated_at":"2024-07-31T03:15:03.000Z","dependencies_parsed_at":"2023-02-19T18:01:40.330Z","dependency_job_id":null,"html_url":"https://github.com/github/ruby-gpgme","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fruby-gpgme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fruby-gpgme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fruby-gpgme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fruby-gpgme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/github","download_url":"https://codeload.github.com/github/ruby-gpgme/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235232788,"owners_count":18957058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T21:11:06.211Z","updated_at":"2025-10-04T08:31:54.378Z","avatar_url":"https://github.com/github.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"= GPGME\n\nThis README is better viewed through the YARD formatted documentation:\nhttp://rdoc.info/github/ueno/ruby-gpgme/frames for latest github\nversion, or http://rdoc.info/gems/gpgme for latest gem release.\n\n{\u003cimg src=\"https://travis-ci.org/ueno/ruby-gpgme.png?branch=master\" alt=\"Build Status\" /\u003e}[https://travis-ci.org/ueno/ruby-gpgme]\n{\u003cimg src=\"https://coveralls.io/repos/ueno/ruby-gpgme/badge.png\" alt=\"Coverage Status\" /\u003e}[https://coveralls.io/r/ueno/ruby-gpgme]\n\n== Requirements\n\n* Ruby 1.8 or later\n* GPGME 1.1.2 or later\n* gpg-agent (optional, but recommended)\n\n== Installation\n\n $ gem install gpgme\n\n== API\n\nGPGME provides three levels of API. The highest level API is as simple as it\ngets, the mid level API provides more functionality but might be less\nuser-friendly, and the lowest level API is close to the C interface of GPGME.\n\n=== The highest level API\n\nFor example, to create a cleartext signature of the plaintext from\nstdin and write the result to stdout can be written as follows.\n\n crypto = GPGME::Crypto.new\n crypto.clearsign $stdin, :output =\u003e $stdout\n\n=== The mid level API\n\nThe same example can be rewritten in the mid level API as follows.\n\n plain = GPGME::Data.new($stdin)\n sig   = GPGME::Data.new($stdout)\n GPGME::Ctx.new do |ctx|\n   ctx.sign(plain, sig, GPGME::SIG_MODE_CLEAR)\n end\n\n=== The lowest level API\n\nThe same example can be rewritten in the lowest level API as follows.\n\n ret = []\n GPGME::gpgme_new(ret)\n ctx = ret.shift\n GPGME::gpgme_data_new_from_fd(ret, 0)\n plain = ret.shift\n GPGME::gpgme_data_new_from_fd(ret, 1)\n sig = ret.shift\n GPGME::gpgme_op_sign(ctx, plain, sig, GPGME::SIG_MODE_CLEAR)\n\nAs you see, it's much harder to write a program in this API than the\nhighest level API. However, if you are already familiar with the C\ninterface of GPGME and want to control detailed behavior of GPGME, it\nmight be useful.\n\n== Usage\n\nAll the high level methods attack the mid level \u003ctt\u003eGPGME::Ctx\u003c/tt\u003e API. It is\nrecommended to read through the \u003ctt\u003eGPGME::Ctx.new\u003c/tt\u003e methods for common options.\n\nAlso, most of the input/output is done via \u003ctt\u003eGPGME::Data\u003c/tt\u003e objects that create a\ncommon interface for reading/writing to normal strings, or other common\nobjects like files. Read the \u003ctt\u003eGPGME::Data\u003c/tt\u003e documentation to understand\nhow it works. Every time the lib needs a \u003ctt\u003eGPGME::Data\u003c/tt\u003e object, it will be\nautomatically converted to it.\n\n=== Crypto\n\nThe \u003ctt\u003eGPGME::Crypto\u003c/tt\u003e class has the high level convenience methods to encrypt,\ndecrypt, sign and verify signatures. Here are some examples, but it is\nrecommended to read through the \u003ctt\u003eGPGME::Crypto\u003c/tt\u003e class to see all the options.\n\n* Document encryption via \u003ctt\u003eGPGME::Crypto#encrypt\u003c/tt\u003e:\n crypto = GPGME::Crypto.new\n crypto.encrypt \"Hello world!\", :recipients =\u003e \"someone@example.com\"\n\n* Symmetric encryption:\n crypto = GPGME::Crypto.new :password =\u003e \"gpgme\"\n crypto.encrypt \"Hello world!\", :symmetric =\u003e true\n\n\n* Document decryption via \u003ctt\u003eGPGME::Crypto#decrypt\u003c/tt\u003e (including signature verification):\n crypto.decrypt File.open(\"text.gpg\")\n\n* Document signing via \u003ctt\u003eGPGME::Crypto#sign\u003c/tt\u003e. Also the clearsigning and detached signing.\n crypto.sign \"I hereby proclaim Github the beneficiary of all my money when I die\"\n\n* Sign verification via \u003ctt\u003eGPGME::Crypto#verify\u003c/tt\u003e\n sign = crypto.sign \"Some text\"\n data = crypto.verify(sign) { |signature| signature.valid? }\n\n=== Key\n\nThe \u003ctt\u003eGPGME::Key\u003c/tt\u003e object represents a key, and has the high level related\nmethods to work with them and find them, export, import, deletetion and\ncreation.\n\n* Key listing\n GPGME::Key.find(:secret, \"someone@example.com\")\n # =\u003e Returns an array with all the secret keys available in the keychain.\n #    that match \"someone@example.com\"\n\n* Key exporting\n GPGME::Key.export(\"someone@example.com\")\n # =\u003e Returns a GPGME::Data object with the exported key.\n\n key = GPGME::Key.find(:secret, \"someone@example.com\").first\n key.export\n # =\u003e Returns a GPGME::Data object with the exported key.\n\n* Key importing\n GPGME::Key.import(File.open(\"my.key\"))\n\n* Key validation\n GPGME::Key.valid?(public_key)\n # =\u003e Returns wheter this key is valid or not\n\n\n* TODO: Key generation\n\n=== Engine\n\nProvides three convenience methods to obtain information about the gpg engine\none is currently using. For example:\n\n* Getting current information\n GPGME::Engine.info.first\n      # =\u003e #\u003cGPGME::EngineInfo:0x00000100d4fbd8\n             @file_name=\"/usr/local/bin/gpg\",\n             @protocol=0,\n             @req_version=\"1.3.0\",\n             @version=\"1.4.11\"\u003e\n\n* Changing home directory to work with different settings:\n GPGME::Engine.home_dir = '/tmp'\n\n=== Round trip example using keychain keys\n\nRather than importing the keys it's possible to specify the recipient\nwhen performing crypto functions. Here's a roundtrip example,\nand note that as this is for a console, the \u003ctt\u003econf.echo = false\u003c/tt\u003e\nline is to stop IRB complaining when echoing binary data\n\n  # Stop IRB echoing everything, which errors with binary data.\n  # Not required for production code\n  conf.echo = false\n\n  class PassphraseCallback\n    def initialize(passphrase)\n      @passphrase = passphrase\n    end\n\n    def call(*args)\n      fd = args.last\n      io = IO.for_fd(fd, 'w')\n      io.puts(@passphrase)\n      io.flush\n    end\n  end\n\n  # recipients can be found using $ gpg --list-keys --homedir ./keychain_location\n  # pub   2048R/A1B2C3D4 2014-01-17\n  # Use that line to substitute your own. 2048R is the key length and type (RSA in this case)\n\n  # If you want to substitute a non-default keychain into the engine do this:\n  # home_dir = Rails.root.join('keychain_location').to_s\n  # GPGME::Engine.set_info(GPGME::PROTOCOL_OpenPGP, '/usr/local/bin/gpg', home_dir)\n  # Note GPG executable location will change across platforms\n\n\n  crypto = GPGME::Crypto.new\n  options = {:recipients =\u003e 'A1B2C3D4'}\n\n  plaintext = GPGME::Data.new(File.open(Rails.root.join('Gemfile')))\n\n  data = crypto.encrypt plaintext, options\n\n  f = File.open(Rails.root.join('Gemfile.gpg'), 'wb')\n  bytes_written = f.write(data)\n  f.close\n\n  puts bytes_written\n\n\n  crypto = GPGME::Crypto.new\n  options = {:recipients =\u003e 'A1B2C3D4', :passphrase_callback =\u003e PassphraseCallback.new('my_passphrase')}\n\n  cipthertext = GPGME::Data.new(File.open(Rails.root.join('Gemfile.gpg')))\n\n  data = crypto.decrypt cipthertext, options\n  puts data\n\n\n== Contributing\n\nTo run the local test suite you need bundler and gpg:\n\n bundle\n rake compile   # simple rake task to compile the extension\n rake           # runs the test suite\n\n== License\n\nThe library itself is licensed under LGPLv2.1+.  See the file\nCOPYING.LESSER and each file for copyright and warranty information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithub%2Fruby-gpgme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgithub%2Fruby-gpgme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithub%2Fruby-gpgme/lists"}