Class: KmsTools::EncryptedFile
- Inherits:
-
Object
- Object
- KmsTools::EncryptedFile
- Defined in:
- lib/kms-tools/encrypted_file.rb
Overview
Interacts with files and streams for encryption and decryption of large blobs of data
Constant Summary collapse
- META_SIZE_HEADER_LENGTH =
Number of bytes allocated at the beginning of a KMS file noting metadata size. 7 bytes limits metadata to 9.9 MB, which is way too much. Don’t use that much.
7
- DEFAULT_CIPHER =
Default cipher for local encryption
'aes-256-cbc'
- KMS_REQUIRED_ELEMENTS =
Minimum required metadata elements for a KMS file to be valid
%i(encrypted_key encrypted_iv cipher original_extension checksum)
Instance Method Summary collapse
-
#checksum ⇒ string
Get the SHA1 checksum of the decrypted data.
-
#cipher ⇒ string
Get the cipher used for the encrypted file or set the default.
-
#create_from_file(path) ⇒ Hash
Generate metadata from a plaintext file and prepare for encryption.
- #encrypted_data ⇒ Object
-
#encrypted_iv ⇒ string
Get the encrypted initialization vector of the current file, generate a new one if not present.
-
#encrypted_key ⇒ string
Get the encrypted key of the current file, generate a new one if not present.
-
#file_sha(path) ⇒ String
Calculate SHA of a given file by chunks.
-
#initialize(options = {}) ⇒ EncryptedFile
constructor
Creats an EncryptedFile object.
-
#is_valid_kms_file?(yaml) ⇒ Boolean
Verify YAML header of a KMS file to encure necessary information is present to decrypt.
-
#load_encrypted_file(path) ⇒ Hash
Read a KMS encrypted file and populate object metadata from file headers.
-
#original_extension ⇒ string
Get the original extension of the encrypted file.
-
#save_decrypted(path) ⇒ Boolean
Save decrypted data to the provided path.
-
#save_encrypted(path) ⇒ Boolean
Save encrypted data with KMS headers to the provided path.
-
#set_up_encryption_params ⇒ nil
Generate encryption key, iv, and cipher if they do not exist.
Constructor Details
#initialize(options = {}) ⇒ EncryptedFile
Creats an EncryptedFile object.
23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/kms-tools/encrypted_file.rb', line 23 def initialize( = {}) @enc = [:encrypter] || KmsTools::Encrypter.new @dec = KmsTools::Decrypter.new @kms_meta = {} if [:path] if File.readable?([:path]) load_encrypted_file([:path]) else raise "#{[:path]} is not a readable!" end end end |
Instance Method Details
#checksum ⇒ string
Get the SHA1 checksum of the decrypted data
102 103 104 |
# File 'lib/kms-tools/encrypted_file.rb', line 102 def checksum @kms_meta[:checksum] end |
#cipher ⇒ string
Get the cipher used for the encrypted file or set the default
95 96 97 |
# File 'lib/kms-tools/encrypted_file.rb', line 95 def cipher @kms_meta[:cipher] ||= DEFAULT_CIPHER end |
#create_from_file(path) ⇒ Hash
Generate metadata from a plaintext file and prepare for encryption
41 42 43 44 45 46 47 48 |
# File 'lib/kms-tools/encrypted_file.rb', line 41 def create_from_file(path) @decrypted_source = path @kms_meta[:arn] = @enc.master_key_arn @kms_meta[:checksum] = file_sha(path) @kms_meta[:original_extension] = File.extname(path) set_up_encryption_params @kms_meta end |
#encrypted_data ⇒ Object
88 89 90 |
# File 'lib/kms-tools/encrypted_file.rb', line 88 def encrypted_data @kms_meta[:encrypted_data] end |
#encrypted_iv ⇒ string
Get the encrypted initialization vector of the current file, generate a new one if not present
77 78 79 |
# File 'lib/kms-tools/encrypted_file.rb', line 77 def encrypted_iv @kms_meta[:encrypted_iv] ||= @enc.new_encrypted_key end |
#encrypted_key ⇒ string
Get the encrypted key of the current file, generate a new one if not present
70 71 72 |
# File 'lib/kms-tools/encrypted_file.rb', line 70 def encrypted_key @kms_meta[:encrypted_key] ||= @enc.new_encrypted_key end |
#file_sha(path) ⇒ String
Calculate SHA of a given file by chunks
172 173 174 175 176 177 178 179 180 181 |
# File 'lib/kms-tools/encrypted_file.rb', line 172 def file_sha(path) sha1 = Digest::SHA1.new file = File.open(path,'rb') chunk = "" while file.read(STREAM_CHUNK_SIZE, chunk) sha1.update(chunk) end sha1.hexdigest end |
#is_valid_kms_file?(yaml) ⇒ Boolean
Verify YAML header of a KMS file to encure necessary information is present to decrypt
164 165 166 |
# File 'lib/kms-tools/encrypted_file.rb', line 164 def is_valid_kms_file?(yaml) KMS_REQUIRED_ELEMENTS.all? { |e| yaml.has_key? e } end |
#load_encrypted_file(path) ⇒ Hash
Read a KMS encrypted file and populate object metadata from file headers
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/kms-tools/encrypted_file.rb', line 54 def load_encrypted_file(path) = IO.binread(path, META_SIZE_HEADER_LENGTH).to_i kms_yaml = YAML::load(IO.binread(path, , META_SIZE_HEADER_LENGTH)) if is_valid_kms_file?(kms_yaml) @kms_meta = kms_yaml @encrypted_file_path = path @encrypted_data_start = META_SIZE_HEADER_LENGTH + else raise "#{path} is not a valid KMS file!" end @kms_meta end |
#original_extension ⇒ string
Get the original extension of the encrypted file
84 85 86 |
# File 'lib/kms-tools/encrypted_file.rb', line 84 def original_extension @kms_meta[:original_extension] end |
#save_decrypted(path) ⇒ Boolean
Save decrypted data to the provided path
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/kms-tools/encrypted_file.rb', line 142 def save_decrypted(path) path << @kms_meta[:original_extension] unless File.extname(path) == @kms_meta[:original_extension] infile = File.open(@encrypted_file_path, 'rb') outfile = File.open(path, 'wb+') @dec.stream_decrypt_with_data_key({ in: infile, position: @encrypted_data_start, out: outfile, encrypted_iv: encrypted_iv, encrypted_key: encrypted_key, cipher: cipher, checksum: checksum }) outfile.close true end |
#save_encrypted(path) ⇒ Boolean
Save encrypted data with KMS headers to the provided path
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/kms-tools/encrypted_file.rb', line 119 def save_encrypted(path) kms_yaml = @kms_meta.to_yaml = kms_yaml.bytesize.to_s.rjust(META_SIZE_HEADER_LENGTH, "0") infile = File.open(@decrypted_source, 'rb') outfile = File.open(path, 'wb+') outfile << outfile << kms_yaml @enc.stream_encrypt_with_data_key({ in: infile, out: outfile, encrypted_iv: encrypted_iv, encrypted_key: encrypted_key, cipher: cipher }) outfile.close true end |
#set_up_encryption_params ⇒ nil
Generate encryption key, iv, and cipher if they do not exist
108 109 110 111 112 113 |
# File 'lib/kms-tools/encrypted_file.rb', line 108 def set_up_encryption_params encrypted_key encrypted_iv cipher return nil end |