Module: Legion::Data::Encryption::Cipher

Defined in:
lib/legion/data/encryption/cipher.rb

Constant Summary collapse

VERSION_BYTE =
"\x01".b.freeze
IV_LENGTH =
12
TAG_LENGTH =
16

Class Method Summary collapse

Class Method Details

.decrypt(blob, key:, aad: '') ⇒ Object

Raises:

  • (ArgumentError)


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/legion/data/encryption/cipher.rb', line 27

def decrypt(blob, key:, aad: '')
  raise ArgumentError, 'data too short' if blob.bytesize < 1 + IV_LENGTH + TAG_LENGTH

  version = blob.byteslice(0, 1)
  raise ArgumentError, "unsupported version: #{version.unpack1('C')}" unless version == VERSION_BYTE

  iv = blob.byteslice(1, IV_LENGTH)
  tag = blob.byteslice(-TAG_LENGTH, TAG_LENGTH)
  ciphertext = blob.byteslice(1 + IV_LENGTH, blob.bytesize - 1 - IV_LENGTH - TAG_LENGTH)

  cipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt
  cipher.key = key
  cipher.iv = iv
  cipher.auth_tag = tag
  cipher.auth_data = aad

  cipher.update(ciphertext) + cipher.final
end

.encrypt(plaintext, key:, aad: '') ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/legion/data/encryption/cipher.rb', line 14

def encrypt(plaintext, key:, aad: '')
  cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
  iv = OpenSSL::Random.random_bytes(IV_LENGTH)
  cipher.key = key
  cipher.iv = iv
  cipher.auth_data = aad

  ciphertext = cipher.update(plaintext.to_s) + cipher.final
  tag = cipher.auth_tag(TAG_LENGTH)

  VERSION_BYTE + iv + ciphertext + tag
end