class Arachni::Support::Crypto::RSA_AES_CBC

Simple hybrid crypto class using RSA for public key encryption and AES with CBC for bulk data encryption/decryption.

RSA is used to encrypt the AES primitives which are used to encrypt the plaintext.

@author Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>

Public Class Methods

new( public_pem, private_pem = nil ) click to toggle source

If only encryption is required the private key parameter can be omitted.

@param [String] public_pem

Location of the Public key in PEM format.

@param [String] private_pem

Location of the Private key in PEM format.
# File lib/arachni/support/crypto/rsa_aes_cbc.rb, line 29
def initialize( public_pem, private_pem = nil )
    @public_pem  = public_pem
    @private_pem = private_pem
end

Public Instance Methods

decrypt( data ) click to toggle source

Decrypts data.

@param [String] data

@return [String]

Plaintext.
# File lib/arachni/support/crypto/rsa_aes_cbc.rb, line 72
def decrypt( data )
    rsa = OpenSSL::PKey::RSA.new( File.read( @private_pem ) )

    # decrypt with 256 bit AES with CBC
    aes = OpenSSL::Cipher::Cipher.new( 'aes-256-cbc' )
    aes.decrypt

    # unencode and unserialize to get the primitives and ciphertext
    primitives = YAML::load( Base64.decode64( data ) )

    aes.key = rsa.private_decrypt( primitives['key'] )
    aes.iv  = rsa.private_decrypt( primitives['iv'] )

    plaintext = aes.update( primitives['ciphertext'] )
    plaintext << aes.final

    plaintext
end
encrypt( data ) click to toggle source

Encrypts data and returns a Base64 representation of the ciphertext and AES CBC primitives encrypted using the public key.

@param [String] data

@return [String]

Base64 representation of the ciphertext and AES CBC primitives encrypted
using the public key.
# File lib/arachni/support/crypto/rsa_aes_cbc.rb, line 42
def encrypt( data )
    rsa = OpenSSL::PKey::RSA.new( File.read( @public_pem ) )

    # encrypt with 256 bit AES with CBC
    aes = OpenSSL::Cipher::Cipher.new( 'aes-256-cbc' )
    aes.encrypt

    # use random key and IV
    aes.key = key = aes.random_key
    aes.iv  = iv  = aes.random_iv

    # this will hold all primitives and ciphertext
    primitives = {}

    primitives['ciphertext'] = aes.update( data )
    primitives['ciphertext'] << aes.final

    primitives['key'] = rsa.public_encrypt( key )
    primitives['iv']  = rsa.public_encrypt( iv )

    # serialize everything and base64 encode it
    Base64.encode64( primitives.to_yaml )
end