NAME
Crypt::NaCl::Sodium::secretbox - Secret-key authenticated encryption (XSalsa20/Poly1305 MAC)
VERSION
version 0.08
SYNOPSIS
use Crypt::NaCl::Sodium qw( :utils );
my $crypto_secretbox = Crypt::NaCl::Sodium->secretbox();
my ($key, $nonce, $decrypted_msg, $msg, $secret);
## Alice
########
# Alice generates secret key
$key = $crypto_secretbox->keygen();
# ... and shares it with Bob
send_to( Bob => { key => $key } );
# now Alice and Bob can start communicating
# Alice generates random nonce
$nonce = $crypto_secretbox->nonce();
send_to( Bob => { nonce => $nonce } );
# Alice's message to Bob
$msg = "Hi Bob!";
# encrypts using combined mode
$secret = $crypto_secretbox->encrypt( $msg, $nonce, $key );
# message is ready for Bob
send_to( Bob => { secret => $secret } );
## Bob
########
# Bob receives the secret key from Alice
$key = receive_for( Bob => 'key' );
# and random nonce
$nonce = receive_for( Bob => 'nonce' );
# Bob is now ready to receive first message from Alice
$secret = receive_for( Bob => 'secret' );
# we have now all information required to decrypt message
$decrypted_msg = $crypto_secretbox->decrypt( $secret, $nonce, $key );
# time to reply
$msg = "Hello Alice!";
# generates new nonce
$nonce = $crypto_secretbox->nonce();
# this time we use detached mode
($mac, $secret) = $crypto_secretbox->encrypt( $msg, $nonce, $key );
# Alice needs all pieces to verify and decrypt Bob's message
send_to( Alice => { nonce => $nonce } );
send_to( Alice => { mac => $mac } );
send_to( Alice => { secret => $secret } );
## Alice
########
# Bob used the detached mode
$nonce = receive_for( Alice => 'nonce' );
$mac = receive_for( Alice => 'mac' );
$secret = receive_for( Alice => 'secret' );
# we have now all information required to decrypt message
$decrypted_msg = $crypto_secretbox->decrypt_detached( $mac, $secret, $nonce, $key );
# NOTE: send_to() and receive_for() and user functions providing transport of
# messages
DESCRIPTION
Secret-key (also known as symmetric-key) cryptography can be compared to combination lock safe - only those who know the correct lock code can open it.
Therefore the generated key must be distributed in secret.
Nonce (number used once) does not have to be protected, but it is crucial that the same nonce has not been ever reused with the same key.
The authentication tag confirms that the encrypted data has not been tampered with before decrypting it.
METHODS
keygen
my $key = $crypto_secretbox->keygen();
Helper method to generate a random key to be used by $crypto_secretbox
.
The length of the $key
equals "KEYBYTES".
NOTE: keep the key confidential.
Returns Data::BytesLocker object.
nonce
my $nonce = $crypto_secretbox->nonce();
Helper method to generate a random nonce to be used by $crypto_secretbox
.
The length of the nonce equals "NONCEBYTES".
If initial value has been passed as the argument, it will then padded with null
bytes.
my $counter = 121;
my $nonce = $crypto_secretbox->nonce($counter);
$nonce =~ /^121\0+$/ or die;
NOTE: nonce does not have to be random nor confidential, but it must never be reused with the same key. It is large enough that the randomly generated nonces have negligible risk of collision.
If random nonce is being used it needs to be provided to the other party to allow decryption.
If counter is being used store it alongside the key to avoid accidental reuse on the next session. In connection-oriented protocols counter-based nonce could help rejecting duplicate messages.
Returns Data::BytesLocker object.
encrypt
# combined mode - MAC and encrypted message stored together
my $secret = $crypto_secretbox->encrypt($msg, $nonce, $key);
# detached mode - MAC and encrypted message returned separate
my ($mac, $ciphertext) = $crypto_secretbox->encrypt($msg, $nonce, $key);
Encrypts the plaintext message using given $nonce
and $key
.
In scalar context works in combined mode, where MAC and encrypted message are stored together. The length of the $secret
is equal to the length of $msg
+ "MACBYTES".
In list context the $mac
and $ciphertext
are returned separately. The length of the $ciphertext
is equal to the length of $msg
, while length of $mac
is "MACBYTES".
Returns Data::BytesLocker object.
decrypt
my $msg;
eval {
$msg = $crypto_secretbox->decrypt($secret, $nonce, $key);
};
if ( $@ ) {
warn "Message forged!";
} else {
print "Decrypted message: $msg\n";
}
Verifies and decrypts the secret message using given $nonce
and $key
.
Function croaks if the verification fails. Otherwise returns the decrypted message.
The length of the $msg
is equal to the length of $secret
- "MACBYTES".
Returns Data::BytesLocker object.
decrypt_detached
my $msg;
eval {
$msg = $crypto_secretbox->decrypt_detached($mac, $ciphertext, $nonce, $key);
};
if ( $@ ) {
warn "Message forged!";
} else {
print "Decrypted message: $msg\n";
}
Verifies and decrypts the secret message $ciphertext
authenticated with $mac
using given $nonce
and $key
.
Function croaks if the verification fails. Otherwise returns the decrypted message.
The length of the $msg
equals the length of $ciphertext
.
Returns Data::BytesLocker object.
CONSTANTS
NONCEBYTES
my $nonce_length = $crypto_secretbox->NONCEBYTES;
Returns the length of nonce.
KEYBYTES
my $key_length = $crypto_secretbox->KEYBYTES;
Returns the length of key.
MACBYTES
my $mac_length = $crypto_secretbox->MACBYTES;
Returns the length of MAC.
ALGORITHM DETAILS
crypto_secretbox
for encryption uses XSalsa20 stream cipher (which is based on Salsa20, but with much longer nonce) and Poly1305 MAC for authentication.
SEE ALSO
Data::BytesLocker - guarded data storage
Extending the Salsa20 nonce - the paper introducing XSalsa20
AUTHOR
Alex J. G. Burzyński <ajgb@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2015 by Alex J. G. Burzyński <ajgb@cpan.org>.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.