Class | MCollective::SSL |
In: |
lib/mcollective/ssl.rb
|
Parent: | Object |
A class that assists in encrypting and decrypting data using a combination of RSA and AES
Data will be AES encrypted for speed, the Key used in # the AES stage will be encrypted using RSA
ssl = SSL.new(public_key, private_key, passphrase) data = File.read("largefile.dat") crypted_data = ssl.encrypt_with_private(data) pp crypted_data
This will result in a hash of data like:
crypted = {:key => "crd4NHvG....=", :data => "XWXlqN+i...=="}
The key and data will all be base 64 encoded already by default you can pass a 2nd parameter as false to encrypt_with_private and counterparts that will prevent the base 64 encoding
You can pass the data hash into ssl.decrypt_with_public which should return your original data
There are matching methods for using a public key to encrypt data to be decrypted using a private key
private_key_file | [R] | |
public_key_file | [R] |
# File lib/mcollective/ssl.rb, line 174 174: def self.base64_decode(string) 175: Base64.decode64(string) 176: end
# File lib/mcollective/ssl.rb, line 165 165: def self.base64_encode(string) 166: Base64.encode64(string) 167: end
# File lib/mcollective/ssl.rb, line 36 36: def initialize(pubkey=nil, privkey=nil, passphrase=nil) 37: @public_key_file = pubkey 38: @private_key_file = privkey 39: 40: @public_key = read_key(:public, pubkey) 41: @private_key = read_key(:private, privkey, passphrase) 42: end
decrypts a string given key, iv and data
# File lib/mcollective/ssl.rb, line 151 151: def aes_decrypt(key, crypt_string) 152: cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc') 153: 154: cipher.decrypt 155: cipher.key = key 156: cipher.pkcs5_keyivgen(key) 157: decrypted_data = cipher.update(crypt_string) + cipher.final 158: end
encrypts a string, returns a hash of key, iv and data
# File lib/mcollective/ssl.rb, line 137 137: def aes_encrypt(plain_string) 138: cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc') 139: cipher.encrypt 140: 141: key = cipher.random_key 142: 143: cipher.key = key 144: cipher.pkcs5_keyivgen(key) 145: encrypted_data = cipher.update(plain_string) + cipher.final 146: 147: {:key => key, :data => encrypted_data} 148: end
base 64 decode a string
# File lib/mcollective/ssl.rb, line 170 170: def base64_decode(string) 171: SSL.base64_decode(string) 172: end
base 64 encode a string
# File lib/mcollective/ssl.rb, line 161 161: def base64_encode(string) 162: SSL.base64_encode(string) 163: end
Decrypts data, expects a hash as create with crypt_with_public
# File lib/mcollective/ssl.rb, line 81 81: def decrypt_with_private(crypted, base64=true) 82: raise "Crypted data should include a key" unless crypted.include?(:key) 83: raise "Crypted data should include data" unless crypted.include?(:data) 84: 85: if base64 86: key = rsa_decrypt_with_private(base64_decode(crypted[:key])) 87: aes_decrypt(key, base64_decode(crypted[:data])) 88: else 89: key = rsa_decrypt_with_private(crypted[:key]) 90: aes_decrypt(key, crypted[:data]) 91: end 92: end
Decrypts data, expects a hash as create with crypt_with_private
# File lib/mcollective/ssl.rb, line 95 95: def decrypt_with_public(crypted, base64=true) 96: raise "Crypted data should include a key" unless crypted.include?(:key) 97: raise "Crypted data should include data" unless crypted.include?(:data) 98: 99: if base64 100: key = rsa_decrypt_with_public(base64_decode(crypted[:key])) 101: aes_decrypt(key, base64_decode(crypted[:data])) 102: else 103: key = rsa_decrypt_with_public(crypted[:key]) 104: aes_decrypt(key, crypted[:data]) 105: end 106: end
Encrypts supplied data using AES and then encrypts using RSA the key and IV
Return a hash with everything optionally base 64 encoded
# File lib/mcollective/ssl.rb, line 66 66: def encrypt_with_private(plain_text, base64=true) 67: crypted = aes_encrypt(plain_text) 68: 69: if base64 70: key = base64_encode(rsa_encrypt_with_private(crypted[:key])) 71: data = base64_encode(crypted[:data]) 72: else 73: key = rsa_encrypt_with_private(crypted[:key]) 74: data = crypted[:data] 75: end 76: 77: {:key => key, :data => data} 78: end
Encrypts supplied data using AES and then encrypts using RSA the key and IV
Return a hash with everything optionally base 64 encoded
# File lib/mcollective/ssl.rb, line 48 48: def encrypt_with_public(plain_text, base64=true) 49: crypted = aes_encrypt(plain_text) 50: 51: if base64 52: key = base64_encode(rsa_encrypt_with_public(crypted[:key])) 53: data = base64_encode(crypted[:data]) 54: else 55: key = rsa_encrypt_with_public(crypted[:key]) 56: data = crypted[:data] 57: end 58: 59: {:key => key, :data => data} 60: end
Reads either a :public or :private key from disk, uses an optional passphrase to read the private key
# File lib/mcollective/ssl.rb, line 180 180: def read_key(type, key=nil, passphrase=nil) 181: return key if key.nil? 182: 183: raise "Could not find key #{key}" unless File.exist?(key) 184: 185: if type == :public 186: return OpenSSL::PKey::RSA.new(File.read(key)) 187: elsif type == :private 188: return OpenSSL::PKey::RSA.new(File.read(key), passphrase) 189: else 190: raise "Can only load :public or :private keys" 191: end 192: end
Use the private key to RSA decrypt data
# File lib/mcollective/ssl.rb, line 116 116: def rsa_decrypt_with_private(crypt_string) 117: raise "No private key set" unless @private_key 118: 119: @private_key.private_decrypt(crypt_string) 120: end
Use the public key to RSA decrypt data
# File lib/mcollective/ssl.rb, line 130 130: def rsa_decrypt_with_public(crypt_string) 131: raise "No public key set" unless @public_key 132: 133: @public_key.public_decrypt(crypt_string) 134: end
Use the private key to RSA encrypt data
# File lib/mcollective/ssl.rb, line 123 123: def rsa_encrypt_with_private(plain_string) 124: raise "No private key set" unless @private_key 125: 126: @private_key.private_encrypt(plain_string) 127: end