Class: SSL
- Inherits:
-
Object
- Object
- SSL
- Defined in:
- lib/ssl.rb
Overview
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 and IV 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 be base 64 encoded already
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
Constant Summary collapse
- PASSWD_CHARS =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@$%^&*()_+{}|":\;?><,./~`'
Instance Attribute Summary collapse
-
#private_key_file ⇒ Object
readonly
Returns the value of attribute private_key_file.
-
#public_key_file ⇒ Object
readonly
Returns the value of attribute public_key_file.
-
#ssl_cipher ⇒ Object
readonly
Returns the value of attribute ssl_cipher.
Instance Method Summary collapse
-
#aes_decrypt(key, crypt_string) ⇒ Object
decrypts a string given key, iv and data.
-
#aes_encrypt(plain_string) ⇒ Object
encrypts a string, returns a hash of key, iv and data.
-
#base64_decode(string) ⇒ Object
base 64 decode a string.
-
#base64_encode(string) ⇒ Object
base 64 encode a string.
-
#crypt_with_private(plain_text) ⇒ Object
Encrypts supplied data using AES and then encrypts using RSA the key and IV.
-
#decrypt_with_private(crypted) ⇒ Object
Decrypts data, expects a hash as create with crypt_with_public.
-
#decrypt_with_public(crypted) ⇒ Object
Decrypts data, expects a hash as create with crypt_with_private.
-
#encrypt_with_public(plain_text) ⇒ Object
Encrypts supplied data using AES and then encrypts using RSA the key and IV.
-
#initialize(pubkey = nil, privkey = nil, passphrase = nil, ssl_cipher = "aes-256-cbc") ⇒ SSL
constructor
A new instance of SSL.
-
#random_string(length = 20) ⇒ Object
returns a random string made up of characters in the constant PASSWD_CHARS.
-
#read_key(type, key = nil, passphrase = nil) ⇒ Object
Reads either a :public or :private key from disk, uses an optional passphrase to read the private key.
-
#rsa_decrypt_with_private(crypt_string) ⇒ Object
Use the private key to RSA decrypt data.
-
#rsa_decrypt_with_public(crypt_string) ⇒ Object
Use the public key to RSA decrypt data.
-
#rsa_encrypt_with_private(plain_string) ⇒ Object
Use the private key to RSA encrypt data.
-
#rsa_encrypt_with_public(plain_string) ⇒ Object
Use the public key to RSA encrypt data.
Constructor Details
#initialize(pubkey = nil, privkey = nil, passphrase = nil, ssl_cipher = "aes-256-cbc") ⇒ SSL
Returns a new instance of SSL.
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ssl.rb', line 35 def initialize(pubkey=nil, privkey=nil, passphrase=nil, ssl_cipher="aes-256-cbc") @public_key_file = pubkey @private_key_file = privkey @public_key = read_key(:public, pubkey) @private_key = read_key(:private, privkey, passphrase) @ssl_cipher = ssl_cipher raise "Unknown SSL cipher #{ssl_cipher}" unless OpenSSL::Cipher.ciphers.include?(ssl_cipher) end |
Instance Attribute Details
#private_key_file ⇒ Object (readonly)
Returns the value of attribute private_key_file.
33 34 35 |
# File 'lib/ssl.rb', line 33 def private_key_file @private_key_file end |
#public_key_file ⇒ Object (readonly)
Returns the value of attribute public_key_file.
33 34 35 |
# File 'lib/ssl.rb', line 33 def public_key_file @public_key_file end |
#ssl_cipher ⇒ Object (readonly)
Returns the value of attribute ssl_cipher.
33 34 35 |
# File 'lib/ssl.rb', line 33 def ssl_cipher @ssl_cipher end |
Instance Method Details
#aes_decrypt(key, crypt_string) ⇒ Object
decrypts a string given key, iv and data
135 136 137 138 139 140 141 142 |
# File 'lib/ssl.rb', line 135 def aes_decrypt(key, crypt_string) cipher = OpenSSL::Cipher::Cipher.new(ssl_cipher) cipher.decrypt cipher.key = key cipher.pkcs5_keyivgen(key) decrypted_data = cipher.update(crypt_string) + cipher.final end |
#aes_encrypt(plain_string) ⇒ Object
encrypts a string, returns a hash of key, iv and data
121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/ssl.rb', line 121 def aes_encrypt(plain_string) cipher = OpenSSL::Cipher::Cipher.new(ssl_cipher) cipher.encrypt key = cipher.random_key cipher.key = key cipher.pkcs5_keyivgen(key) encrypted_data = cipher.update(plain_string) + cipher.final {:key => key, :data => encrypted_data} end |
#base64_decode(string) ⇒ Object
base 64 decode a string
150 151 152 |
# File 'lib/ssl.rb', line 150 def base64_decode(string) Base64.decode64(string) end |
#base64_encode(string) ⇒ Object
base 64 encode a string
145 146 147 |
# File 'lib/ssl.rb', line 145 def base64_encode(string) Base64.encode64(string).chomp end |
#crypt_with_private(plain_text) ⇒ Object
Encrypts supplied data using AES and then encrypts using RSA the key and IV
Return a hash with everything base 64 encoded
63 64 65 66 67 68 69 70 |
# File 'lib/ssl.rb', line 63 def crypt_with_private(plain_text) crypted = aes_encrypt(plain_text) encoded_key = base64_encode(rsa_encrypt_with_private(crypted[:key])) encoded_data = base64_encode(crypted[:data]) {:key => encoded_key, :data => encoded_data} end |
#decrypt_with_private(crypted) ⇒ Object
Decrypts data, expects a hash as create with crypt_with_public
73 74 75 76 77 78 79 80 |
# File 'lib/ssl.rb', line 73 def decrypt_with_private(crypted) raise "Crypted data should include a key" unless crypted.include?(:key) raise "Crypted data should include data" unless crypted.include?(:data) key = rsa_decrypt_with_private(base64_decode(crypted[:key])) aes_decrypt(key, base64_decode(crypted[:data])) end |
#decrypt_with_public(crypted) ⇒ Object
Decrypts data, expects a hash as create with crypt_with_private
83 84 85 86 87 88 89 90 |
# File 'lib/ssl.rb', line 83 def decrypt_with_public(crypted) raise "Crypted data should include a key" unless crypted.include?(:key) raise "Crypted data should include data" unless crypted.include?(:data) key = rsa_decrypt_with_public(base64_decode(crypted[:key])) aes_decrypt(key, base64_decode(crypted[:data])) end |
#encrypt_with_public(plain_text) ⇒ Object
Encrypts supplied data using AES and then encrypts using RSA the key and IV
Return a hash with everything base 64 encoded
50 51 52 53 54 55 56 57 |
# File 'lib/ssl.rb', line 50 def encrypt_with_public(plain_text) crypted = aes_encrypt(plain_text) encoded_key = base64_encode(rsa_encrypt_with_public(crypted[:key])) encoded_data = base64_encode(crypted[:data]) {:key => encoded_key, :data => encoded_data} end |
#random_string(length = 20) ⇒ Object
returns a random string made up of characters in the constant PASSWD_CHARS
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/ssl.rb', line 155 def random_string(length=20) pw = "" nr_chars = PASSWD_CHARS.size srand() length.times { pw << PASSWD_CHARS[ rand( nr_chars ) ] } return pw end |
#read_key(type, key = nil, passphrase = nil) ⇒ Object
Reads either a :public or :private key from disk, uses an optional passphrase to read the private key
169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/ssl.rb', line 169 def read_key(type, key=nil, passphrase=nil) return key if key.nil? raise "Could not find key #{key}" unless File.exist?(key) if type == :public return OpenSSL::PKey::RSA.new(File.read(key)) elsif type == :private return OpenSSL::PKey::RSA.new(File.read(key), passphrase) else raise "Can only load :public or :private keys" end end |
#rsa_decrypt_with_private(crypt_string) ⇒ Object
Use the private key to RSA decrypt data
100 101 102 103 104 |
# File 'lib/ssl.rb', line 100 def rsa_decrypt_with_private(crypt_string) raise "No private key set" unless @private_key @private_key.private_decrypt(crypt_string) end |
#rsa_decrypt_with_public(crypt_string) ⇒ Object
Use the public key to RSA decrypt data
114 115 116 117 118 |
# File 'lib/ssl.rb', line 114 def rsa_decrypt_with_public(crypt_string) raise "No public key set" unless @public_key @public_key.public_decrypt(crypt_string) end |
#rsa_encrypt_with_private(plain_string) ⇒ Object
Use the private key to RSA encrypt data
107 108 109 110 111 |
# File 'lib/ssl.rb', line 107 def rsa_encrypt_with_private(plain_string) raise "No private key set" unless @private_key @private_key.private_encrypt(plain_string) end |
#rsa_encrypt_with_public(plain_string) ⇒ Object
Use the public key to RSA encrypt data
93 94 95 96 97 |
# File 'lib/ssl.rb', line 93 def rsa_encrypt_with_public(plain_string) raise "No public key set" unless @public_key @public_key.public_encrypt(plain_string) end |