Module: KStor::Crypto

Defined in:
lib/kstor/crypto.rb,
lib/kstor/crypto/keys.rb,
lib/kstor/crypto/ascii_armor.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:



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

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



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

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



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

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:



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

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:



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

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:



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

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:



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

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:



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

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:



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

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.



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

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
50
# File 'lib/kstor/crypto.rb', line 40

def key_derive(passphrase, params = nil)
  params ||= key_derive_params_generate
  Log.debug("crypto: kdf params = #{params.to_hash}")
  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