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::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::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::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::Password::Hash`](https://didactic-drunk.github.io/sodium.cr/Sodium/Password/Hash.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::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::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? | | [`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. | | 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 subkey4 = kdf.derive "context2", 1, 64
``` ```
### Password Hashing ### Password based keys
```crystal ```crystal
pwhash = Sodium::Pwhash.new pwcreate = Sodium::Password::Key::Create.new
pwhash.memlimit = Sodium::Pwhash::MEMLIMIT_MIN # Take approximately 1 second to derive a key.
pwhash.opslimit = Sodium::Pwhash::OPSLIMIT_MIN pwcreate.tcost = 1.0
pass = "1234" 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 pwhash.verify hash, pass
``` ```
@ -260,6 +276,8 @@ Ops limit →
| 2097152K | 2.119s | | 2097152K | 2.119s |
| Memory | | Memory |
## Contributing ## Contributing
1. Fork it ( https://github.com/didactic-drunk/sodium.cr/fork ) 1. Fork it ( https://github.com/didactic-drunk/sodium.cr/fork )

View File

@ -23,17 +23,17 @@ puts ""
puts "" puts ""
{% for name in %w(OPSLIMIT_MIN OPSLIMIT_INTERACTIVE OPSLIMIT_MODERATE OPSLIMIT_SENSITIVE OPSLIMIT_MAX) %} {% 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 %} {% end %}
puts "" puts ""
{% for name in %w(MEMLIMIT_MIN MEMLIMIT_INTERACTIVE MEMLIMIT_MAX) %} {% 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 %} {% end %}
puts "" puts ""
{% for name in %w(SALT_SIZE STR_SIZE) %} {% 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 %} {% end %}
puts "" puts ""

View File

@ -2,13 +2,15 @@ require "./lib_sodium"
require "./secure_buffer" require "./secure_buffer"
# [Argon2 Password Hashing](https://libsodium.gitbook.io/doc/password_hashing/the_argon2i_function) # [Argon2 Password Hashing](https://libsodium.gitbook.io/doc/password_hashing/the_argon2i_function)
# * #store #verify #needs_rehash? are used together for password verification. # * `Sodium::Password::Hash`
# * #derive_key is used on it's own to generate password based keys. # * - 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.** # **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 module Sodium::Password
OPSLIMIT_MIN = LibSodium.crypto_pwhash_opslimit_min OPSLIMIT_MIN = LibSodium.crypto_pwhash_opslimit_min
OPSLIMIT_INTERACTIVE = LibSodium.crypto_pwhash_opslimit_interactive OPSLIMIT_INTERACTIVE = LibSodium.crypto_pwhash_opslimit_interactive

View File

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

View File

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

View File

@ -1,6 +1,23 @@
require "./abstract" require "./abstract"
module Sodium::Password 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 class Hash < Abstract
# Apply the most recent password hashing algorithm against a password. # Apply the most recent password hashing algorithm against a password.
# Returns a opaque String which includes: # Returns a opaque String which includes:

View File

@ -1,14 +1,18 @@
# Contains the params necessary for #derive_key. # Contains the params necessary for #derive_key.
class Sodium::Password::Params class Sodium::Password::Params
property mode : Mode
property ops : UInt64 property ops : UInt64
property mem : UInt64 property mem : UInt64
property mode : Mode?
property salt : Bytes? property salt : Bytes?
property key_size : Int32? 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 end
def to_h def to_h
@ -27,14 +31,10 @@ class Sodium::Password::Params
if ks = @key_size if ks = @key_size
hash["key_size"] = ks hash["key_size"] = ks
end end
if au = @auth if v = @verify
hash["auth"] = au hash["verify"] = v
end end
hash hash
end end
def self.from_h(hash)
self.new Pwhash::Mode.parse(hash["mode"]), hash["ops"], hash["mem"], hash["tcost"]?, hash["salt"]?
end
end end