/
secret_box.rb
76 lines (73 loc) · 2.95 KB
/
secret_box.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# encoding: binary
require 'rbnacl/nacl/secret_box/xsalsa20_poly1305_box'
module Crypto
# The SecretBox class boxes and unboxes messages
#
# This class uses the given secret key to encrypt and decrypt messages.
#
# It is VITALLY important that the nonce is a nonce, i.e. it is a number used
# only once for any given pair of keys. If you fail to do this, you
# compromise the privacy of the messages encrypted. Give your nonces a
# different prefix, or have one side use an odd counter and one an even counter.
# Just make sure they are different.
#
# The ciphertexts generated by this class include a 16-byte authenticator which
# is checked as part of the decryption. An invalid authenticator will cause
# the unbox function to raise. The authenticator is not a signature. Once
# you've looked in the box, you've demonstrated the ability to create
# arbitrary valid messages, so messages you send are repudiatable. For
# non-repudiatable messages, sign them before or after encryption.
class SecretBox
attr_reader :primitive
# Create a new SecretBox
#
# Sets up the Box with a secret key fro encrypting and decrypting messages.
#
# @param key [String] The key to encrypt and decrypt with
# @param encoding [Symbol] Parse key from the given encoding
#
# @raise [Crypto::LengthError] on invalid keys
#
# @return [Crypto::SecretBox] The new Box, ready to use
def initialize(key, encoding = :raw, primitive = NaCl::SecretBox::XSalsa20Poly1305Box)
@key = Encoder[encoding].decode(key) if key
@primitive = primitive.new(@key)
end
# Encrypts a message
#
# Encrypts the message with the given nonce to the key set up when
# initializing the class. Make sure the nonce is unique for any given
# key, or you might as well just send plain text.
#
# This function takes care of the padding required by the NaCL C API.
#
# @param nonce [String] A 24-byte string containing the nonce.
# @param message [String] The message to be encrypted.
#
# @raise [Crypto::LengthError] If the nonce is not valid
#
# @return [String] The ciphertext without the nonce prepended (BINARY encoded)
def box(nonce, message)
self.primitive.box(nonce, message)
end
alias encrypt box
# Decrypts a ciphertext
#
# Decrypts the ciphertext with the given nonce using the key setup when
# initializing the class.
#
# This function takes care of the padding required by the NaCL C API.
#
# @param nonce [String] A 24-byte string containing the nonce.
# @param ciphertext [String] The message to be decrypted.
#
# @raise [Crypto::LengthError] If the nonce is not valid
# @raise [Crypto::CryptoError] If the ciphertext cannot be authenticated.
#
# @return [String] The decrypted message (BINARY encoded)
def open(nonce, ciphertext)
self.primitive.open(nonce, ciphertext)
end
alias decrypt open
end
end