Class: EncryptedStrings::AsymmetricCipher

Inherits:
Cipher
  • Object
show all
Defined in:
lib/encrypted_strings/asymmetric_cipher.rb

Overview

Encryption in which the keys used to encrypt/decrypt come in pairs. Also known as public key encryption. Anything that's encrypted using the public key can only be decrypted with the same algorithm and a matching private key. Any message that is encrypted with the private key can only be decrypted with the matching public key.

Source: support.microsoft.com/kb/246071

Encrypting

To encrypt a string using an asymmetric cipher, the location of the public key file must be specified. You can define the default for this value like so:

EncryptedStrings::AsymmetricCipher.default_public_key_file = './public.key'

If these configuration options are not passed in to #encrypt, then the default values will be used. You can override the default values like so:

password = 'shhhh'
password.encrypt(:asymmetric, :public_key_file => './encrypted_public.key')  # => "INy95irZ8AlHmvc6ZAF/ARsTpbqPIB/4bEAKKOebjsayB7NYWtIzpswvzxqf\nNJ5yyuvxfMODrcg7RimEMFkFlg==\n"

An exception will be raised if either the public key file could not be found or the key could not decrypt the public key file.

Decrypting

To decrypt a string using an asymmetric cipher, the location of the private key file must be specified. If this file is itself encrypted, you must also specify the algorithm and password used to seed the symmetric algorithm that will decrypt the plublic key file. You can define defaults for these values like so:

EncryptedStrings::AsymmetricCipher.default_private_key_file = './private.key'
EncryptedStrings::SymmetricCipher.default_algorithm = 'DES-EDE3-CBC'
EncryptedStrings::SymmetricCipher.default_password = 'secret'

If these configuration options are not passed in to #decrypt, then the default values will be used. You can override the default values like so:

password = "INy95irZ8AlHmvc6ZAF/ARsTpbqPIB/4bEAKKOebjsayB7NYWtIzpswvzxqf\nNJ5yyuvxfMODrcg7RimEMFkFlg==\n"
password.decrypt(:asymmetric, :public_key_file => './encrypted_public.key', :password => 'secret') # => "shhhh"

An exception will be raised if either the private key file could not be found or the password could not decrypt the private key file.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Cipher

#can_decrypt?

Constructor Details

#initialize(options = {}) ⇒ AsymmetricCipher

Creates a new cipher that uses an asymmetric encryption strategy.

Configuration options:

  • :private_key_file - Encrypted private key file

  • :public_key_file - Public key file

  • :password - The password to use in the symmetric cipher

  • :algorithm - Algorithm to use symmetrically encrypted strings

Raises:

  • (ArgumentError)

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 83

def initialize(options = {})
  invalid_options = options.keys - [:private_key_file, :public_key_file, :algorithm, :password]
  raise ArgumentError, "Unknown key(s): #{invalid_options.join(", ")}" unless invalid_options.empty?
  
  options = {
    :private_key_file => AsymmetricCipher.default_private_key_file,
    :public_key_file => AsymmetricCipher.default_public_key_file
  }.merge(options)
  
  @public_key = @private_key = nil
  
  self.private_key_file = options[:private_key_file]
  self.public_key_file  = options[:public_key_file]
  raise ArgumentError, 'At least one key file must be specified (:private_key_file or :public_key_file)' unless private_key_file || public_key_file
  
  self.algorithm  = options[:algorithm]
  self.password = options[:password]
  
  super()
end

Class Attribute Details

.default_private_key_fileObject

The default private key to use during encryption. Default is nil.


58
59
60
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 58

def default_private_key_file
  @default_private_key_file
end

.default_public_key_fileObject

The default public key to use during encryption. Default is nil.


61
62
63
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 61

def default_public_key_file
  @default_public_key_file
end

Instance Attribute Details

#algorithmObject

The algorithm to use if the key files are encrypted themselves


71
72
73
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 71

def algorithm
  @algorithm
end

#passwordObject

The password used during symmetric decryption of the key files


74
75
76
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 74

def password
  @password
end

#private_key_fileObject

Private key used for decrypting data


65
66
67
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 65

def private_key_file
  @private_key_file
end

#public_key_fileObject

Public key used for encrypting data


68
69
70
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 68

def public_key_file
  @public_key_file
end

Instance Method Details

#decrypt(data) ⇒ Object

Decrypts the given data. If no private key file has been specified, then a NoPrivateKeyError will be raised.

Raises:


115
116
117
118
119
120
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 115

def decrypt(data)
  raise NoPrivateKeyError, "Private key file: #{private_key_file}" unless private?
  
  decrypted_data = data.unpack('m')[0]
  private_rsa.private_decrypt(decrypted_data)
end

#encrypt(data) ⇒ Object

Encrypts the given data. If no public key file has been specified, then a NoPublicKeyError will be raised.

Raises:


106
107
108
109
110
111
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 106

def encrypt(data)
  raise NoPublicKeyError, "Public key file: #{public_key_file}" unless public?
  
  encrypted_data = public_rsa.public_encrypt(data)
  [encrypted_data].pack('m')
end

#private?Boolean

Does this cipher have a private key available?

Returns:

  • (Boolean)

141
142
143
144
145
146
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 141

def private?
  return true if @private_key
  
  load_private_key
  !@private_key.nil?
end

#public?Boolean

Does this cipher have a public key available?

Returns:

  • (Boolean)

133
134
135
136
137
138
# File 'lib/encrypted_strings/asymmetric_cipher.rb', line 133

def public?
  return true if @public_key
  
  load_public_key
  !@public_key.nil?
end