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.



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.



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.



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.



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.



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.



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.



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.



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.



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.



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.



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