Class: ActiveCipherStorage::StreamCipher
- Inherits:
-
Object
- Object
- ActiveCipherStorage::StreamCipher
- Includes:
- KeyUtils
- Defined in:
- lib/active_cipher_storage/stream_cipher.rb
Instance Method Summary collapse
- #decrypt(input_io, output_io) ⇒ Object
- #decrypt_to_io(io) ⇒ Object
- #encrypt(input_io, output_io) ⇒ Object
- #encrypt_to_io(io) ⇒ Object
-
#initialize(config = ActiveCipherStorage.configuration) ⇒ StreamCipher
constructor
A new instance of StreamCipher.
Constructor Details
#initialize(config = ActiveCipherStorage.configuration) ⇒ StreamCipher
Returns a new instance of StreamCipher.
8 9 10 11 12 13 |
# File 'lib/active_cipher_storage/stream_cipher.rb', line 8 def initialize(config = ActiveCipherStorage.configuration) config.validate! @config = config @provider = config.provider @chunk_size = config.chunk_size end |
Instance Method Details
#decrypt(input_io, output_io) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/active_cipher_storage/stream_cipher.rb', line 45 def decrypt(input_io, output_io) header = Format.read_header(input_io) raise Errors::InvalidFormat, "Payload is not chunked; use Cipher#decrypt" unless header.chunked key = @provider.decrypt_data_key(header.encrypted_dek) loop do frame = Format.read_chunk(input_io) raise Errors::InvalidFormat, "Unexpected end of stream — missing final frame" if frame.nil? output_io.write(decrypt_chunk(frame[:ciphertext], key, frame[:iv], frame[:auth_tag], frame[:seq])) break if frame[:seq] == Format::FINAL_SEQ end ensure zero_bytes!(key) end |
#decrypt_to_io(io) ⇒ Object
68 69 70 71 72 73 |
# File 'lib/active_cipher_storage/stream_cipher.rb', line 68 def decrypt_to_io(io) out = StringIO.new("".b) decrypt(io, out) out.rewind out end |
#encrypt(input_io, output_io) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/active_cipher_storage/stream_cipher.rb', line 15 def encrypt(input_io, output_io) dek_bundle = @provider.generate_data_key key = dek_bundle.fetch(:plaintext_key) Format.write_header(output_io, Format::Header.new( version: Format::VERSION, algorithm: Format::ALGO_AES256GCM, chunked: true, chunk_size: @chunk_size, provider_id: @provider.provider_id, encrypted_dek: dek_bundle.fetch(:encrypted_key) )) seq = 0 done = false until done plaintext = input_io.read(@chunk_size) || "".b done = plaintext.bytesize < @chunk_size seq += 1 frame_seq = done ? Format::FINAL_SEQ : seq iv = SecureRandom.random_bytes(Format::IV_SIZE) ct, tag = encrypt_chunk(plaintext, key, iv, frame_seq) Format.write_chunk(output_io, seq: frame_seq, iv: iv, ciphertext: ct, auth_tag: tag) end seq ensure zero_bytes!(key) end |
#encrypt_to_io(io) ⇒ Object
61 62 63 64 65 66 |
# File 'lib/active_cipher_storage/stream_cipher.rb', line 61 def encrypt_to_io(io) out = StringIO.new("".b) encrypt(io, out) out.rewind out end |