NAME

Crypt::NaCl::Sodium::secretbox - Secret-key authenticated encryption (XSalsa20/Poly1305 MAC)

VERSION

version 1.0.8.0

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

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.