| 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] | |
| ssl_cipher | [R] |
# File lib/mcollective/ssl.rb, line 180
180: def self.base64_decode(string)
181: Base64.decode64(string)
182: end
# File lib/mcollective/ssl.rb, line 171
171: def self.base64_encode(string)
172: Base64.encode64(string)
173: end
# 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
decrypts a string given key, iv and data
# 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
# 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
# File lib/mcollective/ssl.rb, line 176
176: def base64_decode(string)
177: SSL.base64_decode(string)
178: end
base 64 encode a string
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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