Class: Familia::Encryption::Providers::XChaCha20Poly1305Provider
- Inherits:
-
Familia::Encryption::Provider
- Object
- Familia::Encryption::Provider
- Familia::Encryption::Providers::XChaCha20Poly1305Provider
- Defined in:
- lib/familia/encryption/providers/xchacha20_poly1305_provider.rb
Constant Summary collapse
- ALGORITHM =
'xchacha20poly1305'.freeze
- NONCE_SIZE =
24- AUTH_TAG_SIZE =
16
Instance Attribute Summary
Attributes inherited from Familia::Encryption::Provider
#algorithm, #auth_tag_size, #nonce_size
Class Method Summary collapse
Instance Method Summary collapse
-
#decrypt(ciphertext, key, nonce, auth_tag, additional_data = nil) ⇒ Object
-
#derive_key(master_key, context, personal: nil) ⇒ String
Derives a context-specific encryption key using BLAKE2b.
-
#encrypt(plaintext, key, additional_data = nil) ⇒ Object
-
#generate_nonce ⇒ Object
-
#secure_wipe(key) ⇒ Object
Clear key from memory (no security guarantees in Ruby).
Methods inherited from Familia::Encryption::Provider
Constructor Details
This class inherits a constructor from Familia::Encryption::Provider
Class Method Details
.available? ⇒ Boolean
38 39 40 |
# File 'lib/familia/encryption/providers/xchacha20_poly1305_provider.rb', line 38 def self.available? !!defined?(RbNaCl) end |
.priority ⇒ Object
42 43 44 |
# File 'lib/familia/encryption/providers/xchacha20_poly1305_provider.rb', line 42 def self.priority 100 # Highest priority - best in class end |
Instance Method Details
#decrypt(ciphertext, key, nonce, auth_tag, additional_data = nil) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/familia/encryption/providers/xchacha20_poly1305_provider.rb', line 61 def decrypt(ciphertext, key, nonce, auth_tag, additional_data = nil) validate_key_length!(key) box = RbNaCl::AEAD::XChaCha20Poly1305IETF.new(key) ciphertext_with_tag = ciphertext + auth_tag aad = additional_data.to_s box.decrypt(nonce, ciphertext_with_tag, aad) rescue RbNaCl::CryptoError raise EncryptionError, 'Decryption failed - invalid key or corrupted data' end |
#derive_key(master_key, context, personal: nil) ⇒ String
Derives a context-specific encryption key using BLAKE2b.
The personalization parameter provides cryptographic domain separation, ensuring that derived keys are unique per application even when using identical master keys and contexts. This prevents key reuse across different applications or library versions.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/familia/encryption/providers/xchacha20_poly1305_provider.rb', line 88 def derive_key(master_key, context, personal: nil) validate_key_length!(master_key) raw_personal = personal || Familia.config.encryption_personalization if raw_personal.include?("\0") raise EncryptionError, 'Personalization string must not contain null bytes' end personal_string = raw_personal.ljust(16, "\0") RbNaCl::Hash.blake2b( context.force_encoding('BINARY'), key: master_key, digest_size: 32, personal: personal_string ) end |
#encrypt(plaintext, key, additional_data = nil) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/familia/encryption/providers/xchacha20_poly1305_provider.rb', line 46 def encrypt(plaintext, key, additional_data = nil) validate_key_length!(key) nonce = generate_nonce box = RbNaCl::AEAD::XChaCha20Poly1305IETF.new(key) aad = additional_data.to_s ciphertext_with_tag = box.encrypt(nonce, plaintext.to_s, aad) { ciphertext: ciphertext_with_tag[0...-16], auth_tag: ciphertext_with_tag[-16..-1], nonce: nonce } end |
#generate_nonce ⇒ Object
73 74 75 |
# File 'lib/familia/encryption/providers/xchacha20_poly1305_provider.rb', line 73 def generate_nonce RbNaCl::Random.random_bytes(NONCE_SIZE) end |
#secure_wipe(key) ⇒ Object
Clear key from memory (no security guarantees in Ruby)
105 106 107 |
# File 'lib/familia/encryption/providers/xchacha20_poly1305_provider.rb', line 105 def secure_wipe(key) key&.clear end |