Class: AEAD::Cipher
- Inherits:
-
Object
- Object
- AEAD::Cipher
- Defined in:
- lib/aead/cipher.rb
Overview
Wraps AEAD ciphers in a simplified interface.
Direct Known Subclasses
AES_128_GCM, AES_256_CBC_HMAC_SHA_256, AES_256_CTR_HMAC_SHA_256, AES_256_GCM
Defined Under Namespace
Modules: AES_GCM, AES_HMAC Classes: AES_128_GCM, AES_256_CBC_HMAC_SHA_256, AES_256_CTR_HMAC_SHA_256, AES_256_GCM
Class Method Summary collapse
-
.generate_key ⇒ String
Returns a securely-generated key of appropriate length for the current Cipher.
-
.generate_nonce ⇒ String
Returns a unique nonce for the current Cipher.
-
.new(algorithm, options = {}) ⇒ Class
Returns a particular Cipher implementation.
-
.signature_compare(left, right) ⇒ Boolean
Does a constant-time comparison between two strings.
Instance Method Summary collapse
-
#decrypt(nonce, aad, aead) ⇒ String
Decrypts a plaintext using the current Cipher.
-
#encrypt(nonce, aad, plaintext) ⇒ String
Encrypts a plaintext using the current Cipher.
-
#key_len ⇒ Integer
The length of keys of encryption keys used by the current Cipher.
-
#nonce_len ⇒ Integer
The length of nonces used by the current Cipher.
Class Method Details
.generate_key ⇒ String
Returns a securely-generated key of appropriate length for the current Cipher.
37 38 39 |
# File 'lib/aead/cipher.rb', line 37 def self.generate_key SecureRandom.random_bytes(self.key_len) end |
.generate_nonce ⇒ String
Returns a unique nonce for the current Cipher.
46 47 48 |
# File 'lib/aead/cipher.rb', line 46 def self.generate_nonce AEAD::Nonce.generate end |
.new(algorithm, options = {}) ⇒ Class
Returns a particular Cipher implementation.
22 23 24 25 26 27 28 29 |
# File 'lib/aead/cipher.rb', line 22 def self.new(algorithm, = {}) # run normal Class#new if we're being called from a subclass return super unless self == AEAD::Cipher # TODO: ciphers should register themselves, as opposed to using a # potentiall-unsafe const_get self.const_get algorithm.tr('-', '_').upcase end |
.signature_compare(left, right) ⇒ Boolean
Does a constant-time comparison between two strings. Useful to avoid timing attacks when comparing a generated signature against a user-provided signature.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/aead/cipher.rb', line 59 def self.signature_compare(left, right) # short-circuit if the lengths are inequal return false if left.to_s.bytesize != right.bytesize # Constant-time string comparison algorithm: # 1. Break both strings into bytes # 2. Subtract the strings from one-another, byte by byte # (any non-equal bytes will subtract to a nonzero value) # 3. OR the XOR'd bytes together # 4. If the result is nonzero, the strings differed. left = left.bytes.to_a right = right.bytes.to_a result = 0 left.length.times do |i| result |= left[i] - right[i] end result == 0 end |
Instance Method Details
#decrypt(nonce, aad, aead) ⇒ String
Decrypts a plaintext using the current Cipher.
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/aead/cipher.rb', line 131 def decrypt(nonce, aad, aead) _verify_nonce_bytesize(nonce, self.nonce_len) self._decrypt( _pad_nonce(nonce), aad, _extract_ciphertext(aead, self.tag_len), _extract_tag(aead, self.tag_len) ) end |
#encrypt(nonce, aad, plaintext) ⇒ String
Encrypts a plaintext using the current Cipher.
IMPORTANT: Do not ever encrypt data using the same nonce more than once given a particular secret key. Doing so will violate the security guarantees of the AEAD cipher.
112 113 114 115 116 117 118 119 120 |
# File 'lib/aead/cipher.rb', line 112 def encrypt(nonce, aad, plaintext) _verify_nonce_bytesize(nonce, self.nonce_len) self._encrypt( _pad_nonce(nonce), aad, plaintext ) end |
#key_len ⇒ Integer
The length of keys of encryption keys used by the current Cipher.
85 86 87 |
# File 'lib/aead/cipher.rb', line 85 def key_len self.class.key_len end |
#nonce_len ⇒ Integer
The length of nonces used by the current Cipher.
94 95 96 |
# File 'lib/aead/cipher.rb', line 94 def nonce_len self.class.nonce_len end |