class RbNaCl::Boxes::Curve25519XSalsa20Poly1305
non-repudiable messages, sign them before or after encryption.
arbitrary valid messages, so messages you send are repudiable. For
you’ve looked in the box, you’ve demonstrated the ability to create
the unbox function to raise. The authenticator is not a signature. Once
is checked as part of the decryption. An invalid authenticator will cause
The ciphertexts generated by this class include a 16-byte authenticator which
they are different.
have one side use an odd counter and one an even counter. Just make sure
the property mentioned just above. Give your nonces a different prefix, or
compromise the privacy of the the messages encrypted. Also, bear in mind
only once for any given pair of keys. If you fail to do this, you
It is VITALLY important that the nonce is a nonce, i.e. it is a number used
# Bob gets a RbNaCl::CryptoError to deal with!
# BOOM!
alicebob_box.open(nonce2, cipher_text_to_bob_honest_love_eve)
# [nonce2, cipher_text_to_bob_honest_love_eve]
# But Eve has tampered with this message, by flipping some bytes around!
# we have a new message!
#=> “Hey there, Bob!”
plain_text = alicebob_box.open(nonce, cipher_text_to_bob)
# random
# that is too fiddly to type here. But there are other choices than just
# Alice has been a little more sensible than bob, and has a random nonce
# decrypt the reply
# receive [nonce, cipher_text_to_bob] from alice
# note that nonces don’t have to be secret
# send [“A bad example of a nonce”, cipher_text] to alice
#=> “…” # a string of bytes, 29 bytes long
cipher_text = alicebob_box.box(“A bad example of a nonce”, “Hello, Alice!”)
# encrypt a message to alice
#=> #<RbNaCl::Box …>
alicebob_box = RbNaCl::Box.new(alice_pubkey, bobkey)
# make a box
alice_pubkey = “…”
# is left as an exercise to for the reader.
# NB: This is actually the hard part of the system. How to do it securely
# receive alice’s public key, alicepk
# send bobkey.public_key to alice
#=> #<RbNaCl::PrivateKey …>
bobkey = RbNaCl::PrivateKey.generate
# On bob’s system
@example
equal that from (pkbob, skalice). This is how the system works:
skalice) and bob(pkbob, skbob), the key derived from (pkalice, skbob) with
both pairing of keys, so given two keypairs belonging to alice (pkalice,
decrypt the given ciphertexts. The same shared key will generated from
which is used with the nonce given to encrypt the given messages and
This class uses the given public and secret keys to derive a shared key,
The Box class boxes and unboxes messages between a pair of keys
def self.nonce_bytes
-
(Integer)
- The number of bytes in a valid nonce
def self.nonce_bytes NONCEBYTES end
def beforenm
def beforenm @beforenm ||= begin key = Util.zeros(BEFORENMBYTES) success = self.class.box_curve25519xsalsa20poly1305_beforenm(key, @public_key.to_s, @private_key.to_s) raise CryptoError, "Failed to derive shared key" unless success key end end
def box(nonce, message)
-
(String)
- The ciphertext without the nonce prepended (BINARY encoded)
Raises:
-
(RbNaCl::LengthError)
- If the nonce is not valid
Parameters:
-
message
(String
) -- The message to be encrypted. -
nonce
(String
) -- A 24-byte string containing the nonce.
def box(nonce, message) Util.check_length(nonce, nonce_bytes, "Nonce") msg = Util.prepend_zeros(ZEROBYTES, message) ct = Util.zeros(msg.bytesize) success = self.class.box_curve25519xsalsa20poly1305_afternm(ct, msg, msg.bytesize, nonce, beforenm) raise CryptoError, "Encryption failed" unless success Util.remove_zeros(BOXZEROBYTES, ct) end
def initialize(public_key, private_key)
-
(RbNaCl::Box)
- The new Box, ready to use
Raises:
-
(RbNaCl::LengthError)
- on invalid keys
Parameters:
-
private_key
(String, RbNaCl::PrivateKey
) -- The private key to encrypt with -
public_key
(String, RbNaCl::PublicKey
) -- The public key to encrypt to
def initialize(public_key, private_key) @public_key = public_key.is_a?(PublicKey) ? public_key : PublicKey.new(public_key) @private_key = private_key.is_a?(PrivateKey) ? private_key : PrivateKey.new(private_key) raise IncorrectPrimitiveError unless @public_key.primitive == primitive && @private_key.primitive == primitive end
def nonce_bytes
-
(Integer)
- The number of bytes in a valid nonce
def nonce_bytes NONCEBYTES end
def open(nonce, ciphertext)
-
(String)
- The decrypted message (BINARY encoded)
Raises:
-
(RbNaCl::CryptoError)
- If the ciphertext cannot be authenticated. -
(RbNaCl::LengthError)
- If the nonce is not valid
Parameters:
-
ciphertext
(String
) -- The message to be decrypted. -
nonce
(String
) -- A 24-byte string containing the nonce.
def open(nonce, ciphertext) Util.check_length(nonce, nonce_bytes, "Nonce") ct = Util.prepend_zeros(BOXZEROBYTES, ciphertext) message = Util.zeros(ct.bytesize) success = self.class.box_curve25519xsalsa20poly1305_open_afternm(message, ct, ct.bytesize, nonce, beforenm) raise CryptoError, "Decryption failed. Ciphertext failed verification." unless success Util.remove_zeros(ZEROBYTES, message) end
def primitive
-
(Symbol)
- The primitive used
def primitive self.class.primitive end