Module: SshTresor::Crypto Private
- Defined in:
- lib/ssh_tresor/crypto.rb
Overview
This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.
Cryptographic primitives used by the envelope encryption construction.
This module intentionally exposes small byte-oriented helpers. Higher-level callers should normally use Vault.
Constant Summary collapse
- CHALLENGE_SIZE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
32- MASTER_KEY_SIZE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
32- NONCE_SIZE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
12- AUTH_TAG_SIZE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
16
Class Method Summary collapse
-
.decrypt(key, nonce, ciphertext_with_tag) ⇒ String
private
Decrypts ciphertext produced by Crypto.encrypt.
-
.derive_key(signature) ⇒ String
private
Derives a slot-wrapping key from SSH-agent signature bytes.
-
.encrypt(key, nonce, plaintext) ⇒ String
private
Encrypts plaintext with AES-256-GCM.
-
.random_challenge ⇒ String
private
Generates a random SSH-agent signing challenge.
-
.random_master_key ⇒ String
private
Generates a fresh data master key.
-
.random_nonce ⇒ String
private
Generates a fresh AES-GCM nonce.
Class Method Details
.decrypt(key, nonce, ciphertext_with_tag) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Decrypts ciphertext produced by encrypt.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/ssh_tresor/crypto.rb', line 85 def decrypt(key, nonce, ciphertext_with_tag) raise DecryptionError, "ciphertext too short" if ciphertext_with_tag.bytesize < AUTH_TAG_SIZE ciphertext = ciphertext_with_tag.byteslice(0, ciphertext_with_tag.bytesize - AUTH_TAG_SIZE) tag = ciphertext_with_tag.byteslice(-AUTH_TAG_SIZE, AUTH_TAG_SIZE) cipher = OpenSSL::Cipher.new("aes-256-gcm") cipher.decrypt cipher.key = key cipher.iv = nonce cipher.auth_tag = tag cipher.auth_data = "".b cipher.update(ciphertext) + cipher.final rescue OpenSSL::Cipher::CipherError raise DecryptionError, "authentication failed - wrong key or corrupted data" end |
.derive_key(signature) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Derives a slot-wrapping key from SSH-agent signature bytes.
48 49 50 51 52 53 54 55 56 |
# File 'lib/ssh_tresor/crypto.rb', line 48 def derive_key(signature) OpenSSL::KDF.hkdf( signature, salt: "ssh-tresor-v3", info: "slot-key-derivation", length: 32, hash: "SHA256" ) end |
.encrypt(key, nonce, plaintext) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Encrypts plaintext with AES-256-GCM.
65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/ssh_tresor/crypto.rb', line 65 def encrypt(key, nonce, plaintext) cipher = OpenSSL::Cipher.new("aes-256-gcm") cipher.encrypt cipher.key = key cipher.iv = nonce cipher.auth_data = "".b ciphertext = cipher.update(plaintext.b) + cipher.final ciphertext + cipher.auth_tag rescue OpenSSL::Cipher::CipherError => e raise Error, "Encryption failed: AES-GCM encryption failed: #{e.}" end |
.random_challenge ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Generates a random SSH-agent signing challenge.
26 27 28 |
# File 'lib/ssh_tresor/crypto.rb', line 26 def random_challenge SecureRandom.random_bytes(CHALLENGE_SIZE) end |
.random_master_key ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Generates a fresh data master key.
33 34 35 |
# File 'lib/ssh_tresor/crypto.rb', line 33 def random_master_key SecureRandom.random_bytes(MASTER_KEY_SIZE) end |
.random_nonce ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Generates a fresh AES-GCM nonce.
40 41 42 |
# File 'lib/ssh_tresor/crypto.rb', line 40 def random_nonce SecureRandom.random_bytes(NONCE_SIZE) end |