Module: KStor::Crypto

Defined in:
lib/kstor/crypto.rb,
lib/kstor/crypto/keys.rb,
lib/kstor/crypto/ascii_armor.rb,
lib/kstor/crypto/armored_value.rb

Overview

Cryptographic functions for KStor.

Defined Under Namespace

Modules: ASCIIArmor Classes: ArmoredHash, ArmoredValue, KDFParams, KeyPair, PrivateKey, PublicKey, SecretKey

Constant Summary collapse

VERSION =
1

Class Method Summary collapse

Class Method Details

.decrypt_group_privk(group_pubk, owner_privk, encrypted_group_privk) ⇒ PrivateKey

Decrypt and verify group private key.

Parameters:

  • group_pubk (PublicKey)

    group public key to verify signature

  • owner_privk (PrivateKey)

    user private key

  • encrypted_group_privk (ArmoredValue)

    encrypted group private key

Returns:



111
112
113
114
115
# File 'lib/kstor/crypto.rb', line 111

def decrypt_group_privk(group_pubk, owner_privk, encrypted_group_privk)
  PrivateKey.from_binary(
    box_pair_decrypt(group_pubk, owner_privk, encrypted_group_privk)
  )
end

.decrypt_secret_metadata(author_pubk, group_privk, val) ⇒ Hash

Decrypt and verify secret metadata.

Parameters:

Returns:

  • (Hash)

    Hash of keys and values



154
155
156
157
# File 'lib/kstor/crypto.rb', line 154

def (author_pubk, group_privk, val)
  bytes = decrypt_secret_value(author_pubk, group_privk, val)
  ArmoredHash.from_binary(bytes).to_hash
end

.decrypt_secret_value(author_pubk, group_privk, val) ⇒ String

Decrypt and verify secret value.

Parameters:

Returns:

  • (String)

    original secret value



133
134
135
# File 'lib/kstor/crypto.rb', line 133

def decrypt_secret_value(author_pubk, group_privk, val)
  box_pair_decrypt(author_pubk, group_privk, val)
end

.decrypt_user_privk(secret_key, ciphertext) ⇒ PrivateKey

Decrypt user private key.

Parameters:

  • secret_key (SecretKey)

    secret key derived from passphrase

  • ciphertext (ArmoredValue)

    encrypted private key

Returns:



91
92
93
94
# File 'lib/kstor/crypto.rb', line 91

def decrypt_user_privk(secret_key, ciphertext)
  privk_data = box_secret_decrypt(secret_key, ciphertext)
  PrivateKey.from_binary(privk_data)
end

.encrypt_group_privk(owner_pubk, group_privk) ⇒ ArmoredValue

Encrypt and sign group private key.

Parameters:

Returns:



101
102
103
# File 'lib/kstor/crypto.rb', line 101

def encrypt_group_privk(owner_pubk, group_privk)
  box_pair_encrypt(owner_pubk, group_privk, group_privk.to_binary)
end

.encrypt_secret_metadata(group_pubk, author_privk, metadata_as_hash) ⇒ ArmoredValue

Encrypt and sign secret metadata.

Parameters:

  • group_pubk (PublicKey)

    group public key

  • author_privk (PrivateKey)

    user private key

  • metadata_as_hash (Hash)

    Hash of keys and values

Returns:



143
144
145
146
# File 'lib/kstor/crypto.rb', line 143

def (group_pubk, author_privk, )
  meta = ArmoredHash.from_hash()
  encrypt_secret_value(group_pubk, author_privk, meta.to_binary)
end

.encrypt_secret_value(group_pubk, author_privk, value) ⇒ ArmoredValue

Encrypt and sign secret value.

Parameters:

  • group_pubk (PublicKey)

    group public key

  • author_privk (PrivateKey)

    user private key

  • value (String)

    secret value

Returns:



123
124
125
# File 'lib/kstor/crypto.rb', line 123

def encrypt_secret_value(group_pubk, author_privk, value)
  box_pair_encrypt(group_pubk, author_privk, value)
end

.encrypt_user_privk(secret_key, privk) ⇒ ArmoredValue

Encrypt user private key.

Parameters:

  • secret_key (SecretKey)

    secret key derived from passphrase

  • privk (PrivateKey)

    private key

Returns:



82
83
84
# File 'lib/kstor/crypto.rb', line 82

def encrypt_user_privk(secret_key, privk)
  box_secret_encrypt(secret_key, privk.to_binary)
end

.generate_key_pairArray<PublicKey, PrivateKey>

Generate new key pair.

Returns:



70
71
72
73
74
75
# File 'lib/kstor/crypto.rb', line 70

def generate_key_pair
  privk = RbNaCl::PrivateKey.generate
  pubk = privk.public_key
  [PublicKey.from_binary(pubk.to_bytes),
   PrivateKey.from_binary(privk.to_bytes)]
end

.kdf_params_obsolete?(params) ⇒ Boolean

Check if KDF params match current code in this library.

If it is obsolete, you should generate a new secret key from the user’s passphrase, and re-encrypt everything that was encrypted with the old secret key.

Parameters:

  • params (String)

    KDF params as an opaque string.

Returns:

  • (Boolean)

    false if parameters match current library version.



59
60
61
62
63
64
65
# File 'lib/kstor/crypto.rb', line 59

def kdf_params_obsolete?(params)
  return true if params_str.nil?

  params['_version'] != VERSION
rescue RbNaCl::CryptoError => e
  raise Error.for_code('CRYPTO/RBNACL', e.message)
end

.key_derive(passphrase, params = nil) ⇒ SecretKey

Derive a secret key suitable for symetric encryption from a passphrase.

Key derivation function can use previously stored parameters (as an opaque String) or pass nil to generate random parameters.

Parameters:

  • passphrase (String)

    user passphrase as clear text

  • params (KDFParams, nil) (defaults to: nil)

    KDF parameters; if nil, use defaults.

Returns:

  • (SecretKey)

    secret key and KDF parameters



40
41
42
43
44
45
46
47
48
49
# File 'lib/kstor/crypto.rb', line 40

def key_derive(passphrase, params = nil)
  params ||= key_derive_params_generate
  data = RbNaCl::PasswordHash.argon2(
    passphrase, params['salt'],
    params['opslimit'], params['memlimit'], params['digest_size']
  )
  SecretKey.new(ArmoredValue.from_binary(data), params)
rescue RbNaCl::CryptoError => e
  raise Error.for_code('CRYPTO/RBNACL', e.message)
end