Crypt::PK::DSA - Public key cryptography based on DSA
### OO interface #Encryption: Alice my $pub = Crypt::PK::DSA->new('Bob_pub_dsa1.der'); my $ct = $pub->encrypt("secret message"); # #Encryption: Bob (received ciphertext $ct) my $priv = Crypt::PK::DSA->new('Bob_priv_dsa1.der'); my $pt = $priv->decrypt($ct); #Signature: Alice my $priv = Crypt::PK::DSA->new('Alice_priv_dsa1.der'); my $sig = $priv->sign_message($message); # #Signature: Bob (received $message + $sig) my $pub = Crypt::PK::DSA->new('Alice_pub_dsa1.der'); $pub->verify_message($sig, $message) or die "ERROR"; #Key generation my $pk = Crypt::PK::DSA->new(); $pk->generate_key(30, 256); my $private_der = $pk->export_key_der('private'); my $public_der = $pk->export_key_der('public'); my $private_pem = $pk->export_key_pem('private'); my $public_pem = $pk->export_key_pem('public'); ### Functional interface #Encryption: Alice my $ct = dsa_encrypt('Bob_pub_dsa1.der', "secret message"); #Encryption: Bob (received ciphertext $ct) my $pt = dsa_decrypt('Bob_priv_dsa1.der', $ct); #Signature: Alice my $sig = dsa_sign_message('Alice_priv_dsa1.der', $message); #Signature: Bob (received $message + $sig) dsa_verify_message('Alice_pub_dsa1.der', $sig, $message) or die "ERROR";
my $pk = Crypt::PK::DSA->new(); #or my $pk = Crypt::PK::DSA->new($priv_or_pub_key_filename); #or my $pk = Crypt::PK::DSA->new(\$buffer_containing_priv_or_pub_key);
Support for password protected PEM keys
my $pk = Crypt::PK::DSA->new($priv_pem_key_filename, $password); #or my $pk = Crypt::PK::DSA->new(\$buffer_containing_priv_pem_key, $password);
Uses Yarrow-based cryptographically strong random number generator seeded with random data taken from /dev/random (UNIX) or CryptGenRandom (Win32).
/dev/random
CryptGenRandom
$pk->generate_key($group_size, $modulus_size); # $group_size ... in bytes .. 15 < $group_size < 1024 # $modulus_size .. in bytes .. ($modulus_size - $group_size) < 512 ### Bits of Security according to libtomcrypt documentation # 80 bits => generate_key(20, 128) # 120 bits => generate_key(30, 256) # 140 bits => generate_key(35, 384) # 160 bits => generate_key(40, 512) ### Sizes according section 4.2 of FIPS 186-4 # (L and N are the bit lengths of p and q respectively) # L = 1024, N = 160 => generate_key(20, 128) # L = 2048, N = 224 => generate_key(28, 256) # L = 2048, N = 256 => generate_key(32, 256) # L = 3072, N = 256 => generate_key(32, 384)
Loads private or public key in DER or PEM format.
$pk->import_key($filename); #or $pk->import_key(\$buffer_containing_key);
$pk->import_key($pem_filename, $password); #or $pk->import_key(\$buffer_containing_pem_key, $password);
my $private_der = $pk->export_key_der('private'); #or my $public_der = $pk->export_key_der('public');
my $private_pem = $pk->export_key_pem('private'); #or my $public_pem = $pk->export_key_pem('public'); #or my $public_pem = $pk->export_key_pem('public_x509');
With parameter 'public' uses header and footer lines:
'public'
-----BEGIN DSA PUBLIC KEY------ -----END DSA PUBLIC KEY------
With parameter 'public_x509' uses header and footer lines:
'public_x509'
-----BEGIN PUBLIC KEY------ -----END PUBLIC KEY------
my $private_pem = $pk->export_key_pem('private', $password); #or my $private_pem = $pk->export_key_pem('private', $password, $cipher); # supported ciphers: 'DES-CBC' # 'DES-EDE3-CBC' # 'SEED-CBC' # 'CAMELLIA-128-CBC' # 'CAMELLIA-192-CBC' # 'CAMELLIA-256-CBC' # 'AES-128-CBC' # 'AES-192-CBC' # 'AES-256-CBC' (DEFAULT)
my $pk = Crypt::PK::DSA->new($pub_key_filename); my $ct = $pk->encrypt($message); #or my $ct = $pk->encrypt($message, $hash_name); #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
my $pk = Crypt::PK::DSA->new($priv_key_filename); my $pt = $pk->decrypt($ciphertext);
my $pk = Crypt::PK::DSA->new($priv_key_filename); my $signature = $priv->sign_message($message); #or my $signature = $priv->sign_message($message, $hash_name); #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
my $pk = Crypt::PK::DSA->new($pub_key_filename); my $valid = $pub->verify_message($signature, $message) #or my $valid = $pub->verify_message($signature, $message, $hash_name); #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
my $pk = Crypt::PK::DSA->new($priv_key_filename); my $signature = $priv->sign_hash($message_hash);
my $pk = Crypt::PK::DSA->new($pub_key_filename); my $valid = $pub->verify_hash($signature, $message_hash);
my $rv = $pk->is_private; # 1 .. private key loaded # 0 .. public key loaded # undef .. no key loaded
my $size = $pk->size; # returns key size in bytes or undef if no key loaded
my $hash = $pk->key2hash; # returns hash like this (or undef if no key loaded): { type => 1, # integer: 1 .. private, 0 .. public size => 256, # integer: key size in bytes # all the rest are hex strings p => "AAF839A764E04D80824B79FA1F0496C093...", #prime modulus q => "D05C4CB45F29D353442F1FEC43A6BE2BE8...", #prime divisor g => "847E8896D12C9BF18FE283AE7AD58ED7F3...", #generator of a subgroup of order q in GF(p) x => "6C801901AC74E2DC714D75A9F6969483CF...", #private key, random 0 < x < q y => "8F7604D77FA62C7539562458A63C7611B7...", #public key, where y = g^x mod p }
DSA based encryption as implemented by libtomcrypt. See method "encrypt" below.
my $ct = dsa_encrypt($pub_key_filename, $message); #or my $ct = dsa_encrypt(\$buffer_containing_pub_key, $message); #or my $ct = dsa_encrypt($pub_key_filename, $message, $hash_name); #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
Encryption works similar to the Crypt::PK::ECC encryption whereas shared DSA key is computed, and the hash of the shared key XOR'ed against the plaintext forms the ciphertext.
DSA based decryption as implemented by libtomcrypt. See method "decrypt" below.
my $pt = dsa_decrypt($priv_key_filename, $ciphertext); #or my $pt = dsa_decrypt(\$buffer_containing_priv_key, $ciphertext);
Generate DSA signature. See method "sign_message" below.
my $sig = dsa_sign_message($priv_key_filename, $message); #or my $sig = dsa_sign_message(\$buffer_containing_priv_key, $message); #or my $sig = dsa_sign_message($priv_key, $message, $hash_name);
Verify DSA signature. See method "verify_message" below.
dsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; #or dsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; #or dsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
Generate DSA signature. See method "sign_hash" below.
my $sig = dsa_sign_hash($priv_key_filename, $message_hash); #or my $sig = dsa_sign_hash(\$buffer_containing_priv_key, $message_hash);
Verify DSA signature. See method "verify_hash" below.
dsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; #or dsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
### let's have: # DSA private key in PEM format - dsakey.priv.pem # DSA public key in PEM format - dsakey.pub.pem # data file to be signed - input.data
Create signature (from commandline):
openssl dgst -sha1 -sign dsakey.priv.pem -out input.sha1-dsa.sig input.data
Verify signature (Perl code):
use Crypt::PK::DSA; use Crypt::Digest 'digest_file'; use File::Slurp 'read_file'; my $pkdsa = Crypt::PK::DSA->new("dsakey.pub.pem"); my $signature = read_file("input.sha1-dsa.sig", binmode=>':raw'); my $valid = $pkdsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5"); print $valid ? "SUCCESS" : "FAILURE";
Create signature (Perl code):
use Crypt::PK::DSA; use Crypt::Digest 'digest_file'; use File::Slurp 'write_file'; my $pkdsa = Crypt::PK::DSA->new("dsakey.priv.pem"); my $signature = $pkdsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5"); write_file("input.sha1-dsa.sig", {binmode=>':raw'}, $signature);
Verify signature (from commandline):
openssl dgst -sha1 -verify dsakey.pub.pem -signature input.sha1-dsa.sig input.data
Generate keys (Perl code):
use Crypt::PK::DSA; use File::Slurp 'write_file'; my $pkdsa = Crypt::PK::DSA->new; $pkdsa->generate_key(20, 128); write_file("dsakey.pub.der", {binmode=>':raw'}, $pkdsa->export_key_der('public')); write_file("dsakey.priv.der", {binmode=>':raw'}, $pkdsa->export_key_der('private')); write_file("dsakey.pub.pem", $pkdsa->export_key_pem('public_x509')); write_file("dsakey.priv.pem", $pkdsa->export_key_pem('private')); write_file("dsakey-passwd.priv.pem", $pkdsa->export_key_pem('private', 'secret'));
Use keys by OpenSSL:
openssl dsa -in dsakey.priv.der -text -inform der openssl dsa -in dsakey.priv.pem -text openssl dsa -in dsakey-passwd.priv.pem -text -inform pem -passin pass:secret openssl dsa -in dsakey.pub.der -pubin -text -inform der openssl dsa -in dsakey.pub.pem -pubin -text
Generate keys:
openssl dsaparam -genkey -out dsakey.priv.pem 1024 openssl dsa -in dsakey.priv.pem -out dsakey.priv.der -outform der openssl dsa -in dsakey.priv.pem -out dsakey.pub.pem -pubout openssl dsa -in dsakey.priv.pem -out dsakey.pub.der -outform der -pubout openssl dsa -in dsakey.priv.pem -passout pass:secret -des3 -out dsakey-passwd.priv.pem
Load keys (Perl code):
use Crypt::PK::DSA; use File::Slurp 'write_file'; my $pkdsa = Crypt::PK::DSA->new; $pkdsa->import_key("dsakey.pub.der"); $pkdsa->import_key("dsakey.priv.der"); $pkdsa->import_key("dsakey.pub.pem"); $pkdsa->import_key("dsakey.priv.pem"); $pkdsa->import_key("dsakey-passwd.priv.pem", "secret");
https://en.wikipedia.org/wiki/Digital_Signature_Algorithm
To install CryptX, copy and paste the appropriate command in to your terminal.
cpanm
cpanm CryptX
CPAN shell
perl -MCPAN -e shell install CryptX
For more information on module installation, please visit the detailed CPAN module installation guide.