lib/gibberish/rsa.rb in gibberish-0.0.2 vs lib/gibberish/rsa.rb in gibberish-1.0.0

- old
+ new

@@ -1,52 +1,112 @@ module Gibberish - class RSA + # This wraps the OpenSSL RSA functions + # Simply instantiate with a public key or private key + # + # cipher = Gibberish::RSA.new(private_key) + # enc = cipher.encrypt(data) + # dec = cipher.decrypt(enc) + # + # cipher = Gibberish::RSA(public_key) + # cipher.decrypt(enc) + # + # + # You can also generate a keypair using Gibberish::RSA.generate_keypair + # + # kp = Gibberish::RSA.generate_keypair(4096) + # kp.public_key #=> Outputs a Base64 encoded public key + # kp.private_key #=> Outputs the Base64 pem + # + # KeyPair will hand back the private key when passed + # to the RSA class. + # + # cipher = Gibberish::RSA.new(kp) + # + # ## OpenSSL CLI Interop + # + # openssl rsautl -decrypt -inkey [pem_file] -in [BinaryEncodedCryptedFile] + # + # or if you're using the default base64 output, you'll need to decode that first + # + # openssl enc -d -base64 -in [gibberish.crypted] | \ + # openssl rsautl -decrypt -inkey [pem_file] + # + + class RSA class KeyPair def self.generate(bits=2048) self.new(OpenSSL::PKey::RSA.generate(bits)) end + attr_accessor :passphrase + def initialize(key) @key = key + @cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc') end def public_key @key.public_key end def private_key - @key.to_pem + if @passphrase + @key.to_pem(@cipher, @passphrase) + else + @key.to_pem + end end + def to_s + private_key + end + end + # Generate an RSA keypair - defaults to 2048 bits + # + # @param [Integer] bits def RSA.generate_keypair(bits=2048) KeyPair.generate(bits) end # Expects a public key at the minumum # - def initialize(public_key, private_key=nil) - @pub_key = OpenSSL::PKey::RSA.new(public_key) - @priv_key = OpenSSL::PKey::RSA.new(private_key) + # @param [#to_s] key public or private + # @params [String] passphrase to key + # + def initialize(key, passphrase=nil) + @key = OpenSSL::PKey::RSA.new(key.to_s, passphrase) end + # Encrypt data using the key + # + # @param [#to_s] data + # @param [Hash] opts + # @option opts [Boolean] :binary (false) encode the data in binary, not Base64 def encrypt(data, opts={}) - enc = @pub_key.public_encrypt(data) + data = data.to_s + enc = @key.public_encrypt(data) if opts[:binary] enc else Base64.encode64(enc) end end + # Decrypt data using the key + # + # @param [#to_s] data + # @param [Hash] opts + # @option opts [Boolean] :binary (false) don't decode the data as Base64 def decrypt(data, opts={}) - raise "No private key set!" unless @priv_key + data = data.to_s + raise "No private key set!" unless @key.private? unless opts[:binary] data = Base64.decode64(data) end - @priv_key.private_decrypt(data) + @key.private_decrypt(data) end end end