Skip to content

Instantly share code, notes, and snippets.

@upsuper
Created April 12, 2014 13:27
Show Gist options
  • Select an option

  • Save upsuper/10535796 to your computer and use it in GitHub Desktop.

Select an option

Save upsuper/10535796 to your computer and use it in GitHub Desktop.
Secure password - Implementation of a challenge-style password checking flow based on ECDSA. By this method, server will never know the password while it is still able to verify.
#!/usr/bin/env ruby
require "socket"
require "OpenSSL"
Group = OpenSSL::PKey::EC::Group.new("secp160k1")
def send(server, data)
puts ">>> #{data}"
server.puts data
end
def recv(server)
data = server.gets
puts "<<< #{data}"
data
end
def generate_private_key(password)
order = Group.order.to_i
begin
digest = OpenSSL::Digest::SHA1.digest(password)
num = OpenSSL::BN.new(digest, 2).to_i
password = digest
end while num == 0 or num >= order
OpenSSL::BN.new(digest, 2)
end
def generate_public_key(priv_key)
Group.generator.mul(priv_key)
end
def decode_nonce(hex)
OpenSSL::BN.new(hex, 16).to_s 2
end
def sign_data(priv_key, data)
pub_key = generate_public_key(priv_key)
signer = OpenSSL::PKey::EC.new(Group)
signer.private_key = priv_key
signer.public_key = pub_key
OpenSSL::BN.new(signer.dsa_sign_asn1(data), 2)
end
cmd = ARGV[0]
password = ARGV[1]
priv_key = generate_private_key(password)
puts "private key: #{priv_key.to_s 16}"
server = TCPSocket.new 'localhost', 9000
case ARGV[0]
when "set-password"
pub_key = generate_public_key(priv_key)
puts "public key: #{pub_key.to_bn.to_s 16}"
send server, "set-pubkey #{pub_key.to_bn.to_s 16}"
when "verify"
send server, "verify"
_, nonce = recv(server).split
sign = sign_data(priv_key, decode_nonce(nonce))
send server, "sign #{sign.to_s 16}"
_, result = recv(server)
end
#!/usr/bin/env ruby
require "socket"
require "OpenSSL"
Group = OpenSSL::PKey::EC::Group.new("secp160k1")
Verifier = OpenSSL::PKey::EC.new(Group)
def send(client, data)
puts ">>> #{data}"
client.puts data
end
def recv(client)
data = client.gets
puts "<<< #{data}"
data
end
def decode_public_key(hex)
bn = OpenSSL::BN.new(hex, 16)
OpenSSL::PKey::EC::Point.new(Group, bn)
end
def generate_nonce
OpenSSL::BN.new(Random.rand(2 ** 160).to_s)
end
def decode_sign(hex)
OpenSSL::BN.new(hex, 16).to_s 2
end
server = TCPServer.new 9000
loop do
client = server.accept
addr = client.peeraddr
puts "new client at #{addr[2]}:#{addr[1]}"
cmd, arg = recv(client).split
case cmd
when "set-pubkey"
Verifier.public_key = decode_public_key(arg)
when "verify"
nonce = generate_nonce
send client, "nonce #{nonce.to_s 16}"
_, sign = recv(client).split
result = Verifier.dsa_verify_asn1(
nonce.to_s(2), decode_sign(sign))
send client, "result #{result}"
end
client.close
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment