Module: Meshchat::Encryption::AES_RSA

Defined in:
lib/meshchat/encryption/aes_rsa.rb

Overview

Constant Summary collapse

AES_MODE =
:CBC

Class Method Summary collapse

Class Method Details

.decrypt(msg, private_key) ⇒ Object

  1. Split the string in to the AES key and the encrypted message

  2. Decrypt the AES key using the private key

  3. Decrypt the message using the AES key



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/meshchat/encryption/aes_rsa.rb', line 45

def decrypt(msg, private_key)
  # 1
  rsa_encrypted_aes_key = msg[0..255] # 256 bits
  rsa_encrypted_aes_iv = msg[256..511] # next 256 bits
  aes_encrypted_message = msg[512..msg.length]

  # 2
  rsa_decryptor = OpenSSL::PKey::RSA.new private_key
  aes_key = rsa_decryptor.private_decrypt rsa_encrypted_aes_key
  aes_iv = rsa_decryptor.private_decrypt rsa_encrypted_aes_iv

  # 3
  decipher = OpenSSL::Cipher::AES256.new(AES_MODE)
  decipher.decrypt
  decipher.key = aes_key
  decipher.iv = aes_iv

  decipher.update(aes_encrypted_message) + decipher.final
end

.encrypt(msg, public_key) ⇒ Object

  1. Generate random AES key to encrypt message

  2. Use Public Key to encrypt AES Key

  3. Prepend encrypted AES key to the encrypted message

Output message format will look like the following:

{RSA Encrypted AES Key}{RSA Encrypted IV}{AES Encrypted Message}


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/meshchat/encryption/aes_rsa.rb', line 22

def encrypt(msg, public_key)
  # 1
  cipher = OpenSSL::Cipher::AES256.new(AES_MODE)
  cipher.encrypt
  aes_key = cipher.random_key
  aes_iv = cipher.random_iv
  aes_encrypted_message = cipher.update(msg)
  # pad, because of how CBC works
  padding = cipher.final
  encrypted = aes_encrypted_message + padding

  # 2
  rsa_encryptor = OpenSSL::PKey::RSA.new public_key
  rsa_encrypted_aes_key = rsa_encryptor.public_encrypt(aes_key)
  rsa_encrypted_aes_iv = rsa_encryptor.public_encrypt(aes_iv)

  # 3
  rsa_encrypted_aes_key + rsa_encrypted_aes_iv + encrypted
end