Crypt-EECDH
view release on metacpan or search on metacpan
lib/Crypt/EECDH.pm view on Meta::CPAN
}
}
my $random = Bytes::Random::Secure->new( Bits => 128 );
my $private = curve25519_secret_key($random->bytes(32));
my $public = curve25519_public_key($private);
my $shared = curve25519_shared_secret($private, $arg{PublicKey});
my ($encrypt_key, $sign_key) = unpack 'a16 a16', sha256($shared);
my $iv = substr sha256($public), 0, 16;
my $cipher = Crypt::Rijndael->new($encrypt_key, Crypt::Rijndael::MODE_CBC);
$cipher->set_iv($iv);
my $pad_length = 16 - length($arg{Message}) % 16;
my $padding = chr($pad_length) x $pad_length;
my $ciphertext = $cipher->encrypt($arg{Message} . $padding);
my $mac = hmac_sha256($iv . $ciphertext, $sign_key);
return (pack ($format, '', $public, $mac, $ciphertext), $private);
}
sub decrypt {
my ($self, %arg) = @_;
my ($options, $public, $mac, $ciphertext) = unpack $format, $arg{Ciphertext};
die 'Unknown options' if $options ne '';
my $shared = curve25519_shared_secret($arg{Key}, $public);
my ($encrypt_key, $sign_key) = unpack 'a16 a16', sha256($shared);
my $iv = substr sha256($public), 0, 16;
die 'MAC is incorrect' if hmac_sha256($iv . $ciphertext, $sign_key) ne $mac;
my $cipher = Crypt::Rijndael->new($encrypt_key, Crypt::Rijndael::MODE_CBC);
$cipher->set_iv($iv);
my $plaintext = $cipher->decrypt($ciphertext);
my $pad_length = ord substr $plaintext, -1;
substr($plaintext, -$pad_length, $pad_length, '') eq chr($pad_length) x $pad_length or die 'Incorrectly padded';
return ($plaintext, $public);
}
sub keygen {
my ($self, %arg) = @_;
lib/Crypt/EECDH.pm view on Meta::CPAN
=head1 DESCRIPTION
A simple hybrid crypto system with ephemeral ECDH key agreement in
combination with the AES cipher.
=head1 TECHNICAL DETAILS
This modules uses Daniel J. Bernstein's curve25519 to perform a
Diffie-Hellman key agreement. A new keypair is generated for every
encryption operation. The shared key resulting from the key agreement
is hashed and used to encrypt the plaintext using AES in CBC mode
(with the IV deterministically derived from the public key). It also
adds a HMAC, with the key derived from the same shared secret as the
encryption key.
Some of the code in this module (and most of the text of the previous
paragraph) is from the L<Crypt::ECDH_ES> module, which provides
one-way communication functionality in an ephemeral-static mode, where
one side (the decoder or "server") uses a static key.
Crypt::EECDH provides full two-way encryption capability with
( run in 0.860 second using v1.01-cache-2.11-cpan-df04353d9ac )