[1] 08 f9 21 e2 d8 32 d7 57 a3 91 26 2f 8f 5c 49 08 bd f5 7a 43 d7 44 d1 ef 68 7e be 4b a9 68 33 0c 7b 81
attr(,"nonce")
[1] 1f 77 0c be f0 02 7b ae 42 12 5a 47 c5 a0 33 52 e4 87 95 e3 dd 2d c1 bf
Casual Cryptography Using R, Part 4
Well, I thought this post would be the last, but I discovered one last aspect of the sodium library that I will mention here.
The safer library is an interface to the sodium library, and is what I have been using in the first three posts. However, this time I will use the sodium library to discuss the subject of this post.
The aspect covered here is Authenticated Encryption. From the sodium documentation:
Authenticated encryption implements best practices for secure messaging. Even though public keys are not confidential, you should not exchange them over the same insecure channel you are trying to protect. If the connection is being tampered with, the attacker could simply replace the key with another one to hijack the interaction.
What this simply means is a way to determine if a message you send someone has been tampered with in any way. Or, conversely, if the message you receive has been modified, sometimes called a man-in-the-middle attack, to which the above quote is referring.
Authenticated encryption is not addressed in the safer library. We refer to the sodium library for that. The actual method is called auth_encrypt() and auth_decrypt(), where both a private key and public key is used. In addition, a nonce is generated which is non-secret unique data to randomize the cipher. Any tampering will invalidate the encryption. The format for these are:
- auth_encrypt(msg, key, pubkey, nonce = random(24))
- auth_decrypt(bin, key, pubkey, nonce = attr(bin, “nonce”))
Note that the msg vector in the above must be in raw format, not in character format. So, if a message is entered using readline(), it is in character format. To convert it to raw, we can use charToRaw()1 to convert. That phrase might look like this:
auth_encrypt(charToRaw(msg),bob$private_key,alice$public_key)
The authenticated encryption looks a bit different from a standard symmetric or asymmetric encryption, with the addition of the “nonce” field which must be 24 bytes, as so:
This is very similar in function to authenticated signatures used for many digital documents for transmission over the Internet. The structure of this encryption looks like this, where the raw portion’s length will vary depending on the length of the message:
raw [1:34] 08 f9 21 e2 ...
- attr(*, "nonce")= raw [1:24] 1f 77 0c be ...
NULL
But let’s say we wish to establish a secret key with someone we have had no interaction with previously, but still maintain message integrity. The methodology to accomplish this is called Diffie-Hellman key exchange. From the sodium documentation:
The Diffie-Hellman key exchange method allows two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure channel. This key can then be used to encrypt subsequent communications using a symmetric key cipher.
The setup requires each user to generate a random private key and public key, the public key which is exchanged over an insecure channel. Then the parties calculate the same shared secret by combining the private key with the other’s public key using diffie_hellman(). After the shared secret is derived, the private and public keys are disposed, and only the secret derived key is used for communications. The format is:
diffie_hellman(key, pubkey)
The reason only symmetric encryption is available is there is only one key, whereas asymmetric encryption requires two keys. This methodology was covered in the first post on this subject. The shared secret cannot be calculated using only the public keys, so the process is safe from eavesdroppers.
I think this really is the last post on this subject, as there is no reason to delve into the mathematics. Have a great day, and may God Bless you and yours.
Footnotes
To reverse the procedure, we use rawToChar().↩︎