Add Documentation.

This commit is contained in:
Didactic Drunk 2019-09-17 04:20:38 -07:00
parent 3c345f7be8
commit 194ed5f4ef
7 changed files with 68 additions and 29 deletions

View File

@ -83,8 +83,8 @@ Several features in libsodium are already provided by Crystal:
| [`Sodium::Cipher::SecretStream`](https://didactic-drunk.github.io/sodium.cr/Sodium/Cipher/SecretStream/XChaCha20Poly1305.html) | I have a shared key and want encrypt + authenticate streamed data. |
| [`Sodium::Digest::Blake2b`](https://didactic-drunk.github.io/sodium.cr/Sodium/Digest::Blake2b.html) | I want to hash data fast and securely. |
| `Sodium::Digest::SipHash` | I want to hash data really fast and less securely. (Not implemented yet) |
| [`Sodium::Pwhash`](https://didactic-drunk.github.io/sodium.cr/Sodium/Pwhash.html) | I want to hash a password and store it. |
| [`Sodium::Pwhash`](https://didactic-drunk.github.io/sodium.cr/Sodium/Pwhash.html) | I want to derive a key from a password. |
| [`Sodium::Password::Hash`](https://didactic-drunk.github.io/sodium.cr/Sodium/Password/Hash.html) | I want to hash a password and store it. |
| [`Sodium::Password::Key`](https://didactic-drunk.github.io/sodium.cr/Sodium/Password/Key.html) | I want to derive a key from a password. |
| [`Sodium::Kdf`](https://didactic-drunk.github.io/sodium.cr/Sodium/Kdf.html) | I have a high quality master key and want to make subkeys. |
| [`Sodium::Cipher::Chalsa`](https://didactic-drunk.github.io/sodium.cr/Sodium/Cipher/Chalsa.html) | What goes with guacamole? |
| Everything else | I want to design my own crypto protocol and probably do it wrong. |
@ -228,15 +228,31 @@ subkey3 = kdf.derive "context2", 0, 32
subkey4 = kdf.derive "context2", 1, 64
```
### Password Hashing
### Password based keys
```crystal
pwhash = Sodium::Pwhash.new
pwcreate = Sodium::Password::Key::Create.new
pwhash.memlimit = Sodium::Pwhash::MEMLIMIT_MIN
pwhash.opslimit = Sodium::Pwhash::OPSLIMIT_MIN
# Take approximately 1 second to derive a key.
pwcreate.tcost = 1.0
pass = "1234"
hash = pwhash.hash_str pass
key, params = pwcreate.create_key pass
# Store `params` or `params.to_h` for later.
# Derive the same key from the stored params.
pwkey = Sodium::Password::Key.from_params params.to_h
key = pekey.derive_key pass
```
### Password Hashing
```crystal
pwhash = Sodium::Password::Hash.new
pwhash.mem = Sodium::Password::MEMLIMIT_MIN
pwhash.ops = Sodium::Password::OPSLIMIT_MIN
pass = "1234"
hash = pwhash.create pass
pwhash.verify hash, pass
```
@ -260,6 +276,8 @@ Ops limit →
| 2097152K | 2.119s |
| Memory |
## Contributing
1. Fork it ( https://github.com/didactic-drunk/sodium.cr/fork )

View File

@ -23,17 +23,17 @@ puts ""
puts ""
{% for name in %w(OPSLIMIT_MIN OPSLIMIT_INTERACTIVE OPSLIMIT_MODERATE OPSLIMIT_SENSITIVE OPSLIMIT_MAX) %}
puts "Sodium::Password::{{ name.id }} #{Sodium::Pwhash::{{ name.id }}}"
puts "Sodium::Password::{{ name.id }} #{Sodium::Password::{{ name.id }}}"
{% end %}
puts ""
{% for name in %w(MEMLIMIT_MIN MEMLIMIT_INTERACTIVE MEMLIMIT_MAX) %}
puts "Sodium::Password::{{ name.id }} #{Sodium::Pwhash::{{ name.id }}}"
puts "Sodium::Password::{{ name.id }} #{Sodium::Password::{{ name.id }}}"
{% end %}
puts ""
{% for name in %w(SALT_SIZE STR_SIZE) %}
puts "Sodium::Password::{{ name.id }} #{Sodium::Pwhash::{{ name.id }}}"
puts "Sodium::Password::{{ name.id }} #{Sodium::Password::{{ name.id }}}"
{% end %}
puts ""

View File

@ -2,13 +2,15 @@ require "./lib_sodium"
require "./secure_buffer"
# [Argon2 Password Hashing](https://libsodium.gitbook.io/doc/password_hashing/the_argon2i_function)
# * #store #verify #needs_rehash? are used together for password verification.
# * #derive_key is used on it's own to generate password based keys.
# * `Sodium::Password::Hash`
# * - Use for server side authentication replacing scrypt, bcrypt or crypt.
# * `Sodium::Password::Key::Create`
# * - Use to create a key with auto set parameters based on time.
# * - Often used in single user application such as password safes, gpg/ssh keys or other encrypted storage.
# * `Sodium::Password::Key`
# * - Use with the `params` returned by `Create#create_key` or set your own to derive a consistent key or kdf.
#
# **See `examples/pwhash_selector.cr` for help on selecting parameters.**
#
# ## Creating a key for encryption with auto set parameters based on time.
#
module Sodium::Password
OPSLIMIT_MIN = LibSodium.crypto_pwhash_opslimit_min
OPSLIMIT_INTERACTIVE = LibSodium.crypto_pwhash_opslimit_interactive

View File

@ -1,5 +1,4 @@
require "../lib_sodium"
require "../secure_buffer"
require "../password"
abstract class Sodium::Password::Abstract
property ops = OPSLIMIT_INTERACTIVE
@ -29,8 +28,8 @@ abstract class Sodium::Password::Abstract
if pw.responds_to?(:tcost=) && (tcost = hash["tcost"]?)
pw.tcost = tcost.as(Float64)
end
if pw.responds_to?(:auth=) && (auth = hash["auth"]?)
pw.auth = auth.as(Bytes)
if pw.responds_to?(:verify=) && (verify = hash["verify"]?)
pw.verify = verify.as(Bytes)
end
pw

View File

@ -20,12 +20,15 @@ require "./key"
# key, params = pwkc.create_key pass, 32
#
# # Save params.[mode, ops, mem, salt, key_size] to derive the same key later.
# # Or serialize `params.to_h`
# ```
#
# ## Deriving a previously created key.
#
# Usage:
# ```
# pwkey = Sodium::Password::Key.from_params hash
# # Or
# pwkey = Sodium::Password::Key.new
# pwkey.mode = Mode.parse serialized[:mode]
# pwkey.ops = serialized[:ops]

View File

@ -1,6 +1,23 @@
require "./abstract"
module Sodium::Password
# Argon2 password hashing. A modern substitute for scrypt, bcrypt or crypt.
#
# Often used to store password hashes on a server and authenticate clients against the stored hash.
#
# Usage:
# ```crystal
# pwhash = Sodium::Password::Hash.new
#
# pwhash.mem = Sodium::Password::MEMLIMIT_MIN
# pwhash.ops = Sodium::Password::OPSLIMIT_MIN
#
# pass = "1234"
# hash = pwhash.create pass
# pwhash.verify hash, pass
# ```
#
# Use `examples/pwhash_selector.cr` to help choose ops/mem limits.
class Hash < Abstract
# Apply the most recent password hashing algorithm against a password.
# Returns a opaque String which includes:

View File

@ -1,14 +1,18 @@
# Contains the params necessary for #derive_key.
class Sodium::Password::Params
property mode : Mode
property ops : UInt64
property mem : UInt64
property mode : Mode?
property salt : Bytes?
property key_size : Int32?
property tcost : Float64?
property auth : Bytes?
def initialize(@mode, @ops, @mem, @salt = nil, @key_size = nil, @tcost = nil, @auth = nil)
# Information only. Not used to derive a key.
property tcost : Float64?
# Application specific param to verify a password.
property verify : Bytes?
def initialize(@mode, @ops, @mem, @salt = nil, @key_size = nil, @tcost = nil, @verify = nil)
end
def to_h
@ -27,14 +31,10 @@ class Sodium::Password::Params
if ks = @key_size
hash["key_size"] = ks
end
if au = @auth
hash["auth"] = au
if v = @verify
hash["verify"] = v
end
hash
end
def self.from_h(hash)
self.new Pwhash::Mode.parse(hash["mode"]), hash["ops"], hash["mem"], hash["tcost"]?, hash["salt"]?
end
end