# frozen_string_literal: truerequire'openssl'moduleAwsmoduleS3moduleEncryption# @api privatemoduleUtilsUNSAFE_MSG="unsafe encryption, data is longer than key length"class<<selfdefencrypt(key,data)casekeywhenOpenSSL::PKey::RSA# asymmetric encryptionwarn(UNSAFE_MSG)ifkey.public_key.n.num_bits<cipher_size(data)key.public_encrypt(data)whenString# symmetric encryptionwarn(UNSAFE_MSG)ifcipher_size(key)<cipher_size(data)cipher=aes_encryption_cipher(:ECB,key)cipher.update(data)+cipher.finalendenddefdecrypt(key,data)begincasekeywhenOpenSSL::PKey::RSA# asymmetric decryptionkey.private_decrypt(data)whenString# symmetric Decryptioncipher=aes_cipher(:decrypt,:ECB,key,nil)cipher.update(data)+cipher.finalendrescueOpenSSL::Cipher::CipherErrormsg='decryption failed, possible incorrect key'raiseErrors::DecryptionError,msgendenddefdecrypt_aes_gcm(key,data,auth_data)# data is iv (12B) + key + tag (16B)buf=data.unpack('C*')iv=buf[0,12].pack('C*')# iv will always be 12 bytestag=buf[-16,16].pack('C*')# tag is 16 bytesenc_key=buf[12,buf.size-(12+16)].pack('C*')cipher=aes_cipher(:decrypt,:GCM,key,iv)cipher.auth_tag=tagcipher.auth_data=auth_datacipher.update(enc_key)+cipher.finalend# returns the decrypted data + auth_datadefdecrypt_rsa(key,enc_data)# Plaintext must be KeyLengthInBytes (1 Byte) + DataKey + AuthDatabuf=key.private_decrypt(enc_data,OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING).unpack('C*')key_length=buf[0]data=buf[1,key_length].pack('C*')auth_data=buf[key_length+1,buf.length-key_length].pack('C*')[data,auth_data]end# @param [String] block_mode "CBC" or "ECB"# @param [OpenSSL::PKey::RSA, String, nil] key# @param [String, nil] iv The initialization vectordefaes_encryption_cipher(block_mode,key=nil,iv=nil)aes_cipher(:encrypt,block_mode,key,iv)end# @param [String] block_mode "CBC" or "ECB"# @param [OpenSSL::PKey::RSA, String, nil] key# @param [String, nil] iv The initialization vectordefaes_decryption_cipher(block_mode,key=nil,iv=nil)aes_cipher(:decrypt,block_mode,key,iv)end# @param [String] mode "encrypt" or "decrypt"# @param [String] block_mode "CBC" or "ECB"# @param [OpenSSL::PKey::RSA, String, nil] key# @param [String, nil] iv The initialization vectordefaes_cipher(mode,block_mode,key,iv)cipher=key?OpenSSL::Cipher.new("aes-#{cipher_size(key)}-#{block_mode.downcase}"):OpenSSL::Cipher.new("aes-256-#{block_mode.downcase}")cipher.send(mode)# encrypt or decryptcipher.key=keyifkeycipher.iv=ivifivcipherend# @param [String] key# @return [Integer]# @raise ArgumentErrordefcipher_size(key)key.bytesize*8endendendendendend