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

Methods

Attributes

private_key_file  [R] 
public_key_file  [R] 
ssl_cipher  [R] 

Public Class methods

[Source]

     # File lib/mcollective/ssl.rb, line 180
180:         def self.base64_decode(string)
181:             Base64.decode64(string)
182:         end

[Source]

     # File lib/mcollective/ssl.rb, line 171
171:         def self.base64_encode(string)
172:             Base64.encode64(string)
173:         end

[Source]

    # File lib/mcollective/ssl.rb, line 36
36:         def initialize(pubkey=nil, privkey=nil, passphrase=nil, cipher=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: 
43:             @ssl_cipher = "aes-256-cbc"
44:             @ssl_cipher = Config.instance.ssl_cipher if Config.instance.ssl_cipher
45:             @ssl_cipher = cipher if cipher
46: 
47:             raise "The supplied cipher '#{@ssl_cipher}' is not supported" unless OpenSSL::Cipher.ciphers.include?(@ssl_cipher)
48:         end

Public Instance methods

decrypts a string given key, iv and data

[Source]

     # File lib/mcollective/ssl.rb, line 157
157:         def aes_decrypt(key, crypt_string)
158:             cipher = OpenSSL::Cipher::Cipher.new(ssl_cipher)
159: 
160:             cipher.decrypt
161:             cipher.key = key
162:             cipher.pkcs5_keyivgen(key)
163:             decrypted_data = cipher.update(crypt_string) + cipher.final
164:         end

encrypts a string, returns a hash of key, iv and data

[Source]

     # File lib/mcollective/ssl.rb, line 143
143:         def aes_encrypt(plain_string)
144:             cipher = OpenSSL::Cipher::Cipher.new(ssl_cipher)
145:             cipher.encrypt
146: 
147:             key = cipher.random_key
148: 
149:             cipher.key = key
150:             cipher.pkcs5_keyivgen(key)
151:             encrypted_data = cipher.update(plain_string) + cipher.final
152: 
153:             {:key => key, :data => encrypted_data}
154:         end

base 64 decode a string

[Source]

     # File lib/mcollective/ssl.rb, line 176
176:         def base64_decode(string)
177:             SSL.base64_decode(string)
178:         end

base 64 encode a string

[Source]

     # File lib/mcollective/ssl.rb, line 167
167:         def base64_encode(string)
168:             SSL.base64_encode(string)
169:         end

Decrypts data, expects a hash as create with crypt_with_public

[Source]

    # File lib/mcollective/ssl.rb, line 87
87:         def decrypt_with_private(crypted, base64=true)
88:             raise "Crypted data should include a key" unless crypted.include?(:key)
89:             raise "Crypted data should include data" unless crypted.include?(:data)
90: 
91:             if base64
92:                 key = rsa_decrypt_with_private(base64_decode(crypted[:key]))
93:                 aes_decrypt(key, base64_decode(crypted[:data]))
94:             else
95:                 key = rsa_decrypt_with_private(crypted[:key])
96:                 aes_decrypt(key, crypted[:data])
97:             end
98:         end

Decrypts data, expects a hash as create with crypt_with_private

[Source]

     # File lib/mcollective/ssl.rb, line 101
101:         def decrypt_with_public(crypted, base64=true)
102:             raise "Crypted data should include a key" unless crypted.include?(:key)
103:             raise "Crypted data should include data" unless crypted.include?(:data)
104: 
105:             if base64
106:                 key = rsa_decrypt_with_public(base64_decode(crypted[:key]))
107:                 aes_decrypt(key, base64_decode(crypted[:data]))
108:             else
109:                 key = rsa_decrypt_with_public(crypted[:key])
110:                 aes_decrypt(key, crypted[:data])
111:             end
112:         end

Encrypts supplied data using AES and then encrypts using RSA the key and IV

Return a hash with everything optionally base 64 encoded

[Source]

    # File lib/mcollective/ssl.rb, line 72
72:         def encrypt_with_private(plain_text, base64=true)
73:             crypted = aes_encrypt(plain_text)
74: 
75:             if base64
76:                 key = base64_encode(rsa_encrypt_with_private(crypted[:key]))
77:                 data = base64_encode(crypted[:data])
78:             else
79:                 key = rsa_encrypt_with_private(crypted[:key])
80:                 data = crypted[:data]
81:             end
82: 
83:             {:key => key, :data => data}
84:         end

Encrypts supplied data using AES and then encrypts using RSA the key and IV

Return a hash with everything optionally base 64 encoded

[Source]

    # File lib/mcollective/ssl.rb, line 54
54:         def encrypt_with_public(plain_text, base64=true)
55:             crypted = aes_encrypt(plain_text)
56: 
57:             if base64
58:                 key = base64_encode(rsa_encrypt_with_public(crypted[:key]))
59:                 data = base64_encode(crypted[:data])
60:             else
61:                 key = rsa_encrypt_with_public(crypted[:key])
62:                 data = crypted[:data]
63:             end
64: 
65:             {:key => key, :data => data}
66:         end

Reads either a :public or :private key from disk, uses an optional passphrase to read the private key

[Source]

     # File lib/mcollective/ssl.rb, line 186
186:         def read_key(type, key=nil, passphrase=nil)
187:             return key if key.nil?
188: 
189:             raise "Could not find key #{key}" unless File.exist?(key)
190: 
191:             if type == :public
192:                 return OpenSSL::PKey::RSA.new(File.read(key))
193:             elsif type == :private
194:                 return OpenSSL::PKey::RSA.new(File.read(key), passphrase)
195:             else
196:                 raise "Can only load :public or :private keys"
197:             end
198:         end

Use the private key to RSA decrypt data

[Source]

     # File lib/mcollective/ssl.rb, line 122
122:         def rsa_decrypt_with_private(crypt_string)
123:             raise "No private key set" unless @private_key
124: 
125:             @private_key.private_decrypt(crypt_string)
126:         end

Use the public key to RSA decrypt data

[Source]

     # File lib/mcollective/ssl.rb, line 136
136:         def rsa_decrypt_with_public(crypt_string)
137:             raise "No public key set" unless @public_key
138: 
139:             @public_key.public_decrypt(crypt_string)
140:         end

Use the private key to RSA encrypt data

[Source]

     # File lib/mcollective/ssl.rb, line 129
129:         def rsa_encrypt_with_private(plain_string)
130:             raise "No private key set" unless @private_key
131: 
132:             @private_key.private_encrypt(plain_string)
133:         end

Use the public key to RSA encrypt data

[Source]

     # File lib/mcollective/ssl.rb, line 115
115:         def rsa_encrypt_with_public(plain_string)
116:             raise "No public key set" unless @public_key
117: 
118:             @public_key.public_encrypt(plain_string)
119:         end

[Validate]