.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "Crypt::PK::DSA 3"
.TH Crypt::PK::DSA 3 "2022-01-07" "perl v5.26.3" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Crypt::PK::DSA \- Public key cryptography based on DSA
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 1
\& ### OO interface
\&
\& #Encryption: Alice
\& my $pub = Crypt::PK::DSA\->new(\*(AqBob_pub_dsa1.der\*(Aq);
\& my $ct = $pub\->encrypt("secret message");
\& #
\& #Encryption: Bob (received ciphertext $ct)
\& my $priv = Crypt::PK::DSA\->new(\*(AqBob_priv_dsa1.der\*(Aq);
\& my $pt = $priv\->decrypt($ct);
\&
\& #Signature: Alice
\& my $priv = Crypt::PK::DSA\->new(\*(AqAlice_priv_dsa1.der\*(Aq);
\& my $sig = $priv\->sign_message($message);
\& #
\& #Signature: Bob (received $message + $sig)
\& my $pub = Crypt::PK::DSA\->new(\*(AqAlice_pub_dsa1.der\*(Aq);
\& $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(\*(Aqprivate\*(Aq);
\& my $public_der = $pk\->export_key_der(\*(Aqpublic\*(Aq);
\& my $private_pem = $pk\->export_key_pem(\*(Aqprivate\*(Aq);
\& my $public_pem = $pk\->export_key_pem(\*(Aqpublic\*(Aq);
\&
\& ### Functional interface
\&
\& #Encryption: Alice
\& my $ct = dsa_encrypt(\*(AqBob_pub_dsa1.der\*(Aq, "secret message");
\& #Encryption: Bob (received ciphertext $ct)
\& my $pt = dsa_decrypt(\*(AqBob_priv_dsa1.der\*(Aq, $ct);
\&
\& #Signature: Alice
\& my $sig = dsa_sign_message(\*(AqAlice_priv_dsa1.der\*(Aq, $message);
\& #Signature: Bob (received $message + $sig)
\& dsa_verify_message(\*(AqAlice_pub_dsa1.der\*(Aq, $sig, $message) or die "ERROR";
.Ve
.SH "METHODS"
.IX Header "METHODS"
.SS "new"
.IX Subsection "new"
.Vb 5
\& 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(\e$buffer_containing_priv_or_pub_key);
.Ve
.PP
Support for password protected \s-1PEM\s0 keys
.PP
.Vb 3
\& my $pk = Crypt::PK::DSA\->new($priv_pem_key_filename, $password);
\& #or
\& my $pk = Crypt::PK::DSA\->new(\e$buffer_containing_priv_pem_key, $password);
.Ve
.SS "generate_key"
.IX Subsection "generate_key"
Uses Yarrow-based cryptographically strong random number generator seeded with
random data taken from \f(CW\*(C`/dev/random\*(C'\fR (\s-1UNIX\s0) or \f(CW\*(C`CryptGenRandom\*(C'\fR (Win32).
.PP
.Vb 3
\& $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)
\&
\& $pk\->generate_key($param_hash)
\& # $param_hash is { d => $d, p => $p, q => $q }
\& # where $d, $p, $q are hex strings
\&
\& $pk\->generate_key(\e$dsa_param)
\& # $dsa_param is the content of DER or PEM file with DSA params
\& # e.g. openssl dsaparam 2048
.Ve
.SS "import_key"
.IX Subsection "import_key"
Loads private or public key in \s-1DER\s0 or \s-1PEM\s0 format.
.PP
.Vb 3
\& $pk\->import_key($filename);
\& #or
\& $pk\->import_key(\e$buffer_containing_key);
.Ve
.PP
Support for password protected \s-1PEM\s0 keys
.PP
.Vb 3
\& $pk\->import_key($pem_filename, $password);
\& #or
\& $pk\->import_key(\e$buffer_containing_pem_key, $password);
.Ve
.PP
Loading private or public keys form perl hash:
.PP
.Vb 1
\& $pk\->import_key($hashref);
\&
\& # where $hashref is a key exported via key2hash
\& $pk\->import_key({
\& 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
\& });
.Ve
.PP
Supported key formats:
.IP "\(bu" 4
\&\s-1DSA\s0 public keys
.Sp
.Vb 12
\& \-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-
\& MIIBtjCCASsGByqGSM44BAEwggEeAoGBAJKyu+puNMGLpGIhbD1IatnwlI79ePr4
\& YHe2KBhRkheKxWUZRpN1Vd/+usS2IHSJ9op5cSWETiP05d7PMtJaitklw7jhudq3
\& GxNvV/GRdCQm3H6d76FHP88dms4vcDYc6ry6wKERGfNEtZ+4BAKrMZK+gDYsF4Aw
\& U6WVR969kYZhAhUA6w25FgSRmJ8W4XkvC60n8Wv3DpMCgYA4ZFE+3tLOM24PZj9Z
\& rxuqUzZZdR+kIzrsIYpWN9ustbmdKLKwsqIaUIxc5zxHEhbAjAIf8toPD+VEQIpY
\& 7vgJgDhXuPq45BgN19iLTzOJwIhAFXPZvnAdIo9D/AnMw688gT6g6U8QCZwX2XYg
\& ICiVcriYVNcjVKHSFY/X0Oi7CgOBhAACgYB4ZTn4OYT/pjUd6tNhGPtOS3CE1oaj
\& 5ScbetXg4ZDpceEyQi8VG+/ZTbs8var8X77JdEdeQA686cAxpOaVgW8V4odvcmfA
\& BfueiGnPXjqGfppiHAyL1Ngyd+EsXKmKVXZYAVFVI0WuJKiZBSVURU7+ByxOfpGa
\& fZhibr0SggWixQ==
\& \-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
.Ve
.IP "\(bu" 4
\&\s-1DSA\s0 private keys
.Sp
.Vb 12
\& \-\-\-\-\-BEGIN DSA PRIVATE KEY\-\-\-\-\-
\& MIIBuwIBAAKBgQCSsrvqbjTBi6RiIWw9SGrZ8JSO/Xj6+GB3tigYUZIXisVlGUaT
\& dVXf/rrEtiB0ifaKeXElhE4j9OXezzLSWorZJcO44bnatxsTb1fxkXQkJtx+ne+h
\& Rz/PHZrOL3A2HOq8usChERnzRLWfuAQCqzGSvoA2LBeAMFOllUfevZGGYQIVAOsN
\& uRYEkZifFuF5LwutJ/Fr9w6TAoGAOGRRPt7SzjNuD2Y/Wa8bqlM2WXUfpCM67CGK
\& VjfbrLW5nSiysLKiGlCMXOc8RxIWwIwCH/LaDw/lRECKWO74CYA4V7j6uOQYDdfY
\& i08zicCIQBVz2b5wHSKPQ/wJzMOvPIE+oOlPEAmcF9l2ICAolXK4mFTXI1Sh0hWP
\& 19DouwoCgYB4ZTn4OYT/pjUd6tNhGPtOS3CE1oaj5ScbetXg4ZDpceEyQi8VG+/Z
\& Tbs8var8X77JdEdeQA686cAxpOaVgW8V4odvcmfABfueiGnPXjqGfppiHAyL1Ngy
\& d+EsXKmKVXZYAVFVI0WuJKiZBSVURU7+ByxOfpGafZhibr0SggWixQIVAL7Sia03
\& 8bvANjjL9Sitk8slrM6P
\& \-\-\-\-\-END DSA PRIVATE KEY\-\-\-\-\-
.Ve
.IP "\(bu" 4
\&\s-1DSA\s0 private keys in password protected \s-1PEM\s0 format:
.Sp
.Vb 3
\& \-\-\-\-\-BEGIN DSA PRIVATE KEY\-\-\-\-\-
\& Proc\-Type: 4,ENCRYPTED
\& DEK\-Info: DES\-CBC,227ADC3AA0299491
\&
\& UISxBYAxPQMl2eK9LMAeHsssF6IxO+4G2ta2Jn8VE+boJrrH3iSTKeMXGjGaXl0z
\& DwcLGV+KMR70y+cxtTb34rFy+uSpBy10dOQJhxALDbe1XfCDQIUfaXRfMNA3um2I
\& JdZixUD/zcxBOUzao+MCr0V9XlJDgqBhJ5EEr53XHH07Eo5fhiBfbbR9NzdUPFrQ
\& p2ASyZtFh7RXoIBUCQgg21oeLddcNWV7gd/Y46kghO9s0JbJ8C+IsuWEPRSq502h
\& tSoDN6B0sxbVvOUICLLbQaxt7yduTAhRxVIJZ1PWATTVD7CZBVz9uIDZ7LOv+er2
\& 1q3vkwb8E9spPsA240+BnfD571XEop4jrawxC0VKQZ+3cPVLc6jhIsxvzzFQUt67
\& g66v8GUgt7KF3KhVV7qEtntybQWDWb+K/uTIH9Ra8nP820d3Rnl61pPXDPlluteT
\& WSLOvEMN2zRmkaxQNv/tLdT0SYpQtdjw74G3A6T7+KnvinKrjtp1a/AXkCF9hNEx
\& DGbxOYo1UOmk8qdxWCrab34nO+Q8oQc9wjXHG+ZtRYIMoGMKREK8DeL4H1RPNkMf
\& rwXWk8scd8QFmJAb8De1VQ==
\& \-\-\-\-\-END DSA PRIVATE KEY\-\-\-\-\-
.Ve
.IP "\(bu" 4
\&\s-1SSH\s0 public \s-1DSA\s0 keys
.Sp
.Vb 1
\& ssh\-dss AAAAB3NzaC1kc3MAAACBAKU8/avmk...4XOwuEssAVhmwA==
.Ve
.IP "\(bu" 4
\&\s-1SSH\s0 public \s-1DSA\s0 keys (\s-1RFC\-4716\s0 format)
.Sp
.Vb 12
\& \-\-\-\- BEGIN SSH2 PUBLIC KEY \-\-\-\-
\& Comment: "1024\-bit DSA, converted from OpenSSH"
\& AAAAB3NzaC1kc3MAAACBAKU8/avmkFeGnSqwYG7dZnQlG+01QNaxu3F5v0NcL/SRUW7Idp
\& Uq8t14siK0mA6yjphLhOf5t8gugTEVBllP86ANSbFigH7WN3v6ydJWqm60pNhNHN//50cn
\& NtIsXbxeq3VtsI64pkH1OJqeZDHLmu73k4T0EKOzsylSfF/wtVBJAAAAFQChpubLHViwPB
\& +jSvUb8e4THS7PBQAAAIAJD1PMCiTCQa1xyD/NCWOajCufTOIzKAhm6l+nlBVPiKI+262X
\& pYt127Ke4mPL8XJBizoTjSQN08uHMg/8L6W/cdO2aZ+mhkBnS1xAm83DAwqLrDraR1w/4Q
\& RFxr5Vbyy8qnejrPjTJobBN1BGsv84wHkjmoCn6pFIfkGYeATlJgAAAIAHYPU1zMVBTDWr
\& u7SNC4G2UyWGWYYLjLytBVHfQmBa51CmqrSs2kCfGLGA1ynfYENsxcJq9nsXrb4i17H5BH
\& JFkH0g7BUDpeBeLr8gsK3WgfqWwtZsDkltObw9chUD/siK6q/dk/fSIB2Ho0inev7k68Z5
\& ZkNI4XOwuEssAVhmwA==
\& \-\-\-\- END SSH2 PUBLIC KEY \-\-\-\-
.Ve
.SS "export_key_der"
.IX Subsection "export_key_der"
.Vb 3
\& my $private_der = $pk\->export_key_der(\*(Aqprivate\*(Aq);
\& #or
\& my $public_der = $pk\->export_key_der(\*(Aqpublic\*(Aq);
.Ve
.SS "export_key_pem"
.IX Subsection "export_key_pem"
.Vb 5
\& my $private_pem = $pk\->export_key_pem(\*(Aqprivate\*(Aq);
\& #or
\& my $public_pem = $pk\->export_key_pem(\*(Aqpublic\*(Aq);
\& #or
\& my $public_pem = $pk\->export_key_pem(\*(Aqpublic_x509\*(Aq);
.Ve
.PP
With parameter \f(CW\*(Aqpublic\*(Aq\fR uses header and footer lines:
.PP
.Vb 2
\& \-\-\-\-\-BEGIN DSA PUBLIC KEY\-\-\-\-\-\-
\& \-\-\-\-\-END DSA PUBLIC KEY\-\-\-\-\-\-
.Ve
.PP
With parameter \f(CW\*(Aqpublic_x509\*(Aq\fR uses header and footer lines:
.PP
.Vb 2
\& \-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-\-
\& \-\-\-\-\-END PUBLIC KEY\-\-\-\-\-\-
.Ve
.PP
Support for password protected \s-1PEM\s0 keys
.PP
.Vb 3
\& my $private_pem = $pk\->export_key_pem(\*(Aqprivate\*(Aq, $password);
\& #or
\& my $private_pem = $pk\->export_key_pem(\*(Aqprivate\*(Aq, $password, $cipher);
\&
\& # supported ciphers: \*(AqDES\-CBC\*(Aq
\& # \*(AqDES\-EDE3\-CBC\*(Aq
\& # \*(AqSEED\-CBC\*(Aq
\& # \*(AqCAMELLIA\-128\-CBC\*(Aq
\& # \*(AqCAMELLIA\-192\-CBC\*(Aq
\& # \*(AqCAMELLIA\-256\-CBC\*(Aq
\& # \*(AqAES\-128\-CBC\*(Aq
\& # \*(AqAES\-192\-CBC\*(Aq
\& # \*(AqAES\-256\-CBC\*(Aq (DEFAULT)
.Ve
.SS "encrypt"
.IX Subsection "encrypt"
.Vb 4
\& 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 \*(AqSHA1\*(Aq (DEFAULT), \*(AqSHA256\*(Aq or any other hash supported by Crypt::Digest
.Ve
.SS "decrypt"
.IX Subsection "decrypt"
.Vb 2
\& my $pk = Crypt::PK::DSA\->new($priv_key_filename);
\& my $pt = $pk\->decrypt($ciphertext);
.Ve
.SS "sign_message"
.IX Subsection "sign_message"
.Vb 4
\& 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 \*(AqSHA1\*(Aq (DEFAULT), \*(AqSHA256\*(Aq or any other hash supported by Crypt::Digest
.Ve
.SS "verify_message"
.IX Subsection "verify_message"
.Vb 4
\& 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 \*(AqSHA1\*(Aq (DEFAULT), \*(AqSHA256\*(Aq or any other hash supported by Crypt::Digest
.Ve
.SS "sign_hash"
.IX Subsection "sign_hash"
.Vb 2
\& my $pk = Crypt::PK::DSA\->new($priv_key_filename);
\& my $signature = $priv\->sign_hash($message_hash);
.Ve
.SS "verify_hash"
.IX Subsection "verify_hash"
.Vb 2
\& my $pk = Crypt::PK::DSA\->new($pub_key_filename);
\& my $valid = $pub\->verify_hash($signature, $message_hash);
.Ve
.SS "is_private"
.IX Subsection "is_private"
.Vb 4
\& my $rv = $pk\->is_private;
\& # 1 .. private key loaded
\& # 0 .. public key loaded
\& # undef .. no key loaded
.Ve
.SS "size"
.IX Subsection "size"
.Vb 2
\& my $size = $pk\->size;
\& # returns key size (length of the prime p) in bytes or undef if key not loaded
.Ve
.SS "size_q"
.IX Subsection "size_q"
.Vb 2
\& my $size = $pk\->size_q;
\& # returns length of the prime q in bytes or undef if key not loaded
.Ve
.SS "key2hash"
.IX Subsection "key2hash"
.Vb 1
\& 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
\& }
.Ve
.SH "FUNCTIONS"
.IX Header "FUNCTIONS"
.SS "dsa_encrypt"
.IX Subsection "dsa_encrypt"
\&\s-1DSA\s0 based encryption as implemented by libtomcrypt. See method \*(L"encrypt\*(R" below.
.PP
.Vb 5
\& my $ct = dsa_encrypt($pub_key_filename, $message);
\& #or
\& my $ct = dsa_encrypt(\e$buffer_containing_pub_key, $message);
\& #or
\& my $ct = dsa_encrypt($pub_key_filename, $message, $hash_name);
\&
\& #NOTE: $hash_name can be \*(AqSHA1\*(Aq (DEFAULT), \*(AqSHA256\*(Aq or any other hash supported by Crypt::Digest
.Ve
.PP
Encryption works similar to the Crypt::PK::ECC encryption whereas shared \s-1DSA\s0 key is computed, and
the hash of the shared key \s-1XOR\s0'ed against the plaintext forms the ciphertext.
.SS "dsa_decrypt"
.IX Subsection "dsa_decrypt"
\&\s-1DSA\s0 based decryption as implemented by libtomcrypt. See method \*(L"decrypt\*(R" below.
.PP
.Vb 3
\& my $pt = dsa_decrypt($priv_key_filename, $ciphertext);
\& #or
\& my $pt = dsa_decrypt(\e$buffer_containing_priv_key, $ciphertext);
.Ve
.SS "dsa_sign_message"
.IX Subsection "dsa_sign_message"
Generate \s-1DSA\s0 signature. See method \*(L"sign_message\*(R" below.
.PP
.Vb 5
\& my $sig = dsa_sign_message($priv_key_filename, $message);
\& #or
\& my $sig = dsa_sign_message(\e$buffer_containing_priv_key, $message);
\& #or
\& my $sig = dsa_sign_message($priv_key, $message, $hash_name);
.Ve
.SS "dsa_verify_message"
.IX Subsection "dsa_verify_message"
Verify \s-1DSA\s0 signature. See method \*(L"verify_message\*(R" below.
.PP
.Vb 5
\& dsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
\& #or
\& dsa_verify_message(\e$buffer_containing_pub_key, $signature, $message) or die "ERROR";
\& #or
\& dsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
.Ve
.SS "dsa_sign_hash"
.IX Subsection "dsa_sign_hash"
Generate \s-1DSA\s0 signature. See method \*(L"sign_hash\*(R" below.
.PP
.Vb 3
\& my $sig = dsa_sign_hash($priv_key_filename, $message_hash);
\& #or
\& my $sig = dsa_sign_hash(\e$buffer_containing_priv_key, $message_hash);
.Ve
.SS "dsa_verify_hash"
.IX Subsection "dsa_verify_hash"
Verify \s-1DSA\s0 signature. See method \*(L"verify_hash\*(R" below.
.PP
.Vb 3
\& dsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
\& #or
\& dsa_verify_hash(\e$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
.Ve
.SH "OpenSSL interoperability"
.IX Header "OpenSSL interoperability"
.Vb 4
\& ### let\*(Aqs 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
.Ve
.SS "Sign by OpenSSL, verify by Crypt::PK::DSA"
.IX Subsection "Sign by OpenSSL, verify by Crypt::PK::DSA"
Create signature (from commandline):
.PP
.Vb 1
\& openssl dgst \-sha1 \-sign dsakey.priv.pem \-out input.sha1\-dsa.sig input.data
.Ve
.PP
Verify signature (Perl code):
.PP
.Vb 3
\& use Crypt::PK::DSA;
\& use Crypt::Digest \*(Aqdigest_file\*(Aq;
\& use Crypt::Misc \*(Aqread_rawfile\*(Aq;
\&
\& my $pkdsa = Crypt::PK::DSA\->new("dsakey.pub.pem");
\& my $signature = read_rawfile("input.sha1\-dsa.sig");
\& my $valid = $pkdsa\->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5");
\& print $valid ? "SUCCESS" : "FAILURE";
.Ve
.SS "Sign by Crypt::PK::DSA, verify by OpenSSL"
.IX Subsection "Sign by Crypt::PK::DSA, verify by OpenSSL"
Create signature (Perl code):
.PP
.Vb 3
\& use Crypt::PK::DSA;
\& use Crypt::Digest \*(Aqdigest_file\*(Aq;
\& use Crypt::Misc \*(Aqwrite_rawfile\*(Aq;
\&
\& my $pkdsa = Crypt::PK::DSA\->new("dsakey.priv.pem");
\& my $signature = $pkdsa\->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5");
\& write_rawfile("input.sha1\-dsa.sig", $signature);
.Ve
.PP
Verify signature (from commandline):
.PP
.Vb 1
\& openssl dgst \-sha1 \-verify dsakey.pub.pem \-signature input.sha1\-dsa.sig input.data
.Ve
.SS "Keys generated by Crypt::PK::DSA"
.IX Subsection "Keys generated by Crypt::PK::DSA"
Generate keys (Perl code):
.PP
.Vb 2
\& use Crypt::PK::DSA;
\& use Crypt::Misc \*(Aqwrite_rawfile\*(Aq;
\&
\& my $pkdsa = Crypt::PK::DSA\->new;
\& $pkdsa\->generate_key(20, 128);
\& write_rawfile("dsakey.pub.der", $pkdsa\->export_key_der(\*(Aqpublic\*(Aq));
\& write_rawfile("dsakey.priv.der", $pkdsa\->export_key_der(\*(Aqprivate\*(Aq));
\& write_rawfile("dsakey.pub.pem", $pkdsa\->export_key_pem(\*(Aqpublic_x509\*(Aq));
\& write_rawfile("dsakey.priv.pem", $pkdsa\->export_key_pem(\*(Aqprivate\*(Aq));
\& write_rawfile("dsakey\-passwd.priv.pem", $pkdsa\->export_key_pem(\*(Aqprivate\*(Aq, \*(Aqsecret\*(Aq));
.Ve
.PP
Use keys by OpenSSL:
.PP
.Vb 5
\& 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
.Ve
.SS "Keys generated by OpenSSL"
.IX Subsection "Keys generated by OpenSSL"
Generate keys:
.PP
.Vb 5
\& 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
.Ve
.PP
Load keys (Perl code):
.PP
.Vb 1
\& use Crypt::PK::DSA;
\&
\& 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");
.Ve
.SH "SEE ALSO"
.IX Header "SEE ALSO"
.IP "\(bu" 4
<https://en.wikipedia.org/wiki/Digital_Signature_Algorithm>