Class: Nova::Starbound::Encryptors::OpenSSL
- Inherits:
-
Nova::Starbound::Encryptor
- Object
- Nova::Starbound::Encryptor
- Nova::Starbound::Encryptors::OpenSSL
- Defined in:
- lib/nova/starbound/encryptors/openssl.rb
Overview
Handles encryption using the OpenSSL library. Shares the shared secret using RSA public key encryption, creates a HMAC digest of the body using the shared secret as a key, and encrypts the body using AES-256-CBC encryption.
Constant Summary collapse
- RSA_KEY_SIZE =
The RSA key size for the key exchange.
4096- SECRET_SIZE =
The shared secret size, in bytes. If RSA_KEY_SIZE is 4096, this is 256.
RSA_KEY_SIZE / 16
Instance Attribute Summary
Attributes inherited from Nova::Starbound::Encryptor
Class Method Summary collapse
-
.available? ⇒ Boolean
see Encryptor.available?.
Instance Method Summary collapse
-
#decrypt(packet) ⇒ Packet
Decrypts the given packet with the encryptor.
-
#encrypt(packet) ⇒ Packet
Encrypts the given packet with the encryptor.
-
#other_public_key=(public_key) ⇒ void
If we already have a public key, that means that the value that’s passed to this method is the shared secret.
-
#private_key! ⇒ void
Generates the private key for this encryptor.
-
#public_key ⇒ String
If we have already recieved the other public key, we’ll generate the secret here, and return the encrypted version of that secret here.
Methods inherited from Nova::Starbound::Encryptor
encryptor_name, encryptors, #initialize, plaintext?, register!, sorted_encryptors
Constructor Details
This class inherits a constructor from Nova::Starbound::Encryptor
Class Method Details
.available? ⇒ Boolean
see Encryptor.available?
24 25 26 27 28 29 30 31 |
# File 'lib/nova/starbound/encryptors/openssl.rb', line 24 def self.available? @_available ||= begin require 'openssl' true rescue LoadError false end end |
Instance Method Details
#decrypt(packet) ⇒ Packet
Decrypts the given packet with the encryptor.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/nova/starbound/encryptors/openssl.rb', line 50 def decrypt(packet) packet = packet.clone decipher = ::OpenSSL::Cipher::AES256.new(:CBC) decipher.decrypt decipher.key = [:shared_secret] decipher.iv = packet[:nonce] digest = packet[:body][0..63] actual_body = packet[:body][64..-1] if hmac_digest(actual_body) != digest raise EncryptorError, "Digest doesn't match the body." end packet.body = decipher.update(actual_body) + decipher.final packet end |
#encrypt(packet) ⇒ Packet
Encrypts the given packet with the encryptor.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/nova/starbound/encryptors/openssl.rb', line 34 def encrypt(packet) packet = packet.clone cipher = ::OpenSSL::Cipher::AES256.new(:CBC) cipher.encrypt cipher.key = [:shared_secret] # we have to fit the packet's nonce size. packet[:nonce] = cipher.iv = ::OpenSSL::Random.random_bytes(24) encrypted = cipher.update(packet[:body]) + cipher.final packet.body = hmac_digest(encrypted) + encrypted packet end |
#other_public_key=(public_key) ⇒ void
This method returns an undefined value.
If we already have a public key, that means that the value that’s passed to this method is the shared secret. Otherwise, it really is the public key of the other remote. If the passed value is a shared secret, it’s decrypted with our private key and stored. If it’s the other public key, it’s instantized to a openssl RSA key, and stored.
99 100 101 102 103 104 105 106 107 |
# File 'lib/nova/starbound/encryptors/openssl.rb', line 99 def other_public_key=(public_key) if [:public] [:shared_secret] = [:private].private_decrypt(public_key) else [:other_public] = ::OpenSSL::PKey::RSA.new(public_key) end end |
#private_key! ⇒ void
This method returns an undefined value.
Generates the private key for this encryptor.
70 71 72 |
# File 'lib/nova/starbound/encryptors/openssl.rb', line 70 def private_key! [:private] = ::OpenSSL::PKey::RSA.new(RSA_KEY_SIZE) end |
#public_key ⇒ String
If we have already recieved the other public key, we’ll generate the secret here, and return the encrypted version of that secret here. Otherwise, we’ll generate our private key and return that in DER format.
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/nova/starbound/encryptors/openssl.rb', line 80 def public_key if [:other_public] [:shared_secret] = ::OpenSSL::Random.random_bytes(SECRET_SIZE) [:other_public].public_encrypt( [:shared_secret]) else [:public] ||= [:private].public_key.to_der end end |