secure-remote-password

SRP-6a protocol for authentication over an insecure network
1.0.0 Latest release released

Secure Remote Password for Crystal Lang

This is a pure Crystal implementation of the Secure Remote Password protocol (SRP-6a).

SRP is an authentication method that allows the use of user names and passwords over an insecure network connection without revealing the password. If the client side lacks the user's password or the server side lacks the proper verification key, the authentication will fail.

Unlike other common challenge-response autentication protocols, such as Kerberos and SSL, SRP does not rely on an external infrastructure of trusted key servers or certificate management.

HomeKit Accessory Protocol Specification (HAP)

Additional classes for handling HomeKit are included, these changes are made to the SRP protocol:

  • SHA-512 is used as the hash function, replacing SHA-1
  • The Modulus, N, and Generator, g, are specified by the 3072-bit group of RFC 5054
  • The match, M, hash calculation is not padded

References

Installation

Add the dependency to your shard.yml:

  dependencies:
    secure-remote-password:
      github: spider-gazelle/secure-remote-password

Usage

require 'secure-remote-password'

username = "user"
password = "password"

# The username, verifier and salt should be stored in the server database
server_verifier = SecureRemotePassword::Verifier.new
auth = verifier.generate_user_verifier(username, password)
auth # => {username: username, verifier: ..., salt: ...}

# ~~~ Begin Authentication ~~~

client = SecureRemotePassword::Client.new(username, password)
client_a = client.start_authentication

# Send username and client_a to the server
# Client => Server: username, client_a

# Server retrieves user's verifier and salt from the database.
# auth = lookup_user(username)
salt = auth[:salt]
verifier = auth[:verifier]

# Server generates challenge for the client.
challenge, proof = server_verifier.get_challenge_and_proof(username, verifier, salt, client_a)

# Server sends the challenge containing salt and proof (B) to client.
# Server => Client: challenge.salt, challenge.proof (B)

# Client calculates match (M) as a response to the challenge.
client_m = client.process_challenge(challenge)

# Client => Server: username, client_m

# Verify challenge response M.
# The Verifier state is passed in proof (server should persist this during negotiation)
server_h_amk = verifier.verify_session(proof, client_m)
# is nil if authentication failed.


# At this point, the client and server should have a common session key
# that is secure (i.e. not known to an outside party).  To finish
# authentication, they must prove to each other that their keys are
# identical.


# server to send server_h_amk to the client
# Server => Client: server_h_amk

client.verify(server_h_amk) == true

Credit

The original SRP-6a work was done by lamikae in the srp-rb project. The HomeKit implementation by karlentwistle

secure-remote-password:
  github: spider-gazelle/secure-remote-password
  version: ~> 1.0.0
Crystal none

Dependencies 0

Development Dependencies 1

  • ameba
    {'github' => 'veelenga/ameba'}

Dependents 0

Last synced .
search fire star recently