Crypt::NaCl::Sodium::secretbox - Secret-key authenticated encryption (XSalsa20/Poly1305 MAC)
version 1.0.8.0
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
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.
my $key = $crypto_secretbox->keygen();
Helper method to generate a random key to be used by $crypto_secretbox.
$crypto_secretbox
The length of the $key equals "KEYBYTES".
$key
NOTE: keep the key confidential.
Returns Data::BytesLocker object.
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.
null
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.
# 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.
$nonce
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".
$secret
$msg
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".
$mac
$ciphertext
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".
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.
The length of the $msg equals the length of $ciphertext.
my $nonce_length = $crypto_secretbox->NONCEBYTES;
Returns the length of nonce.
my $key_length = $crypto_secretbox->KEYBYTES;
Returns the length of key.
my $mac_length = $crypto_secretbox->MACBYTES;
Returns the length of MAC.
crypto_secretbox for encryption uses XSalsa20 stream cipher (which is based on Salsa20, but with much longer nonce) and Poly1305 MAC for authentication.
crypto_secretbox
Data::BytesLocker - guarded data storage
Extending the Salsa20 nonce - the paper introducing XSalsa20
The Poly1305-AES message-authentication code
Alex J. G. Burzyński <ajgb@cpan.org>
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.
To install Crypt::NaCl::Sodium, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Crypt::NaCl::Sodium
CPAN shell
perl -MCPAN -e shell install Crypt::NaCl::Sodium
For more information on module installation, please visit the detailed CPAN module installation guide.