.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man 5.0102 (Pod::Simple 3.45) .\" .\" 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 .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . 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::X25519 3" .TH Crypt::PK::X25519 3 2024-10-20 "perl v5.40.0" "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::X25519 \- Asymmetric cryptography based on X25519 .SH SYNOPSIS .IX Header "SYNOPSIS" .Vb 1 \& use Crypt::PK::X25519; \& \& #Shared secret \& my $priv = Crypt::PK::X25519\->new(\*(AqAlice_priv_x25519.der\*(Aq); \& my $pub = Crypt::PK::X25519\->new(\*(AqBob_pub_x25519.der\*(Aq); \& my $shared_secret = $priv\->shared_secret($pub); \& \& #Load key \& my $pk = Crypt::PK::X25519\->new; \& my $pk_hex = "EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41"; \& $pk\->import_key_raw(pack("H*", $pk_hex), "public"); \& my $sk = Crypt::PK::X25519\->new; \& my $sk_hex = "002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651"; \& $sk\->import_key_raw(pack("H*", $sk_hex), "private"); \& \& #Key generation \& my $pk = Crypt::PK::X25519\->new\->generate_key; \& 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); \& my $private_raw = $pk\->export_key_raw(\*(Aqprivate\*(Aq); \& my $public_raw = $pk\->export_key_raw(\*(Aqpublic\*(Aq); \& my $private_jwk = $pk\->export_key_jwk(\*(Aqprivate\*(Aq); \& my $public_jwk = $pk\->export_key_jwk(\*(Aqpublic\*(Aq); .Ve .SH DESCRIPTION .IX Header "DESCRIPTION" \&\fISince: CryptX\-0.067\fR .SH METHODS .IX Header "METHODS" .SS new .IX Subsection "new" .Vb 5 \& my $pk = Crypt::PK::X25519\->new(); \& #or \& my $pk = Crypt::PK::X25519\->new($priv_or_pub_key_filename); \& #or \& my $pk = Crypt::PK::X25519\->new(\e$buffer_containing_priv_or_pub_key); .Ve .PP Support for password protected PEM keys .PP .Vb 3 \& my $pk = Crypt::PK::X25519\->new($priv_pem_key_filename, $password); \& #or \& my $pk = Crypt::PK::X25519\->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 (UNIX) or \f(CW\*(C`CryptGenRandom\*(C'\fR (Win32). .PP .Vb 1 \& $pk\->generate_key; .Ve .SS import_key .IX Subsection "import_key" Loads private or public key in DER or PEM format. .PP .Vb 3 \& $pk\->import_key($filename); \& #or \& $pk\->import_key(\e$buffer_containing_key); .Ve .PP Support for password protected PEM keys: .PP .Vb 3 \& $pk\->import_key($filename, $password); \& #or \& $pk\->import_key(\e$buffer_containing_key, $password); .Ve .PP Loading private or public keys form perl hash: .PP .Vb 1 \& $pk\->import_key($hashref); \& \& # the $hashref is either a key exported via key2hash \& $pk\->import_key({ \& curve => "x25519", \& pub => "EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41", \& priv => "002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651", \& }); \& \& # or a hash with items corresponding to JWK (JSON Web Key) \& $pk\->import_key({ \& kty => "OKP", \& crv => "X25519", \& d => "AC\-T0Qulco2N2OlSdyHaujJhwLsb7957S72sYx1FRlE", \& x => "6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE", \& }); .Ve .PP Supported key formats: .PP .Vb 2 \& # all formats can be loaded from a file \& my $pk = Crypt::PK::X25519\->new($filename); \& \& # or from a buffer containing the key \& my $pk = Crypt::PK::X25519\->new(\e$buffer_with_key); .Ve .IP \(bu 4 X25519 private keys in PEM format .Sp .Vb 3 \& \-\-\-\-\-BEGIN X25519 PRIVATE KEY\-\-\-\-\- \& MC4CAQAwBQYDK2VuBCIEIAAvk9ELpXKNjdjpUnch2royYcC7G+/ee0u9rGMdRUZR \& \-\-\-\-\-END X25519 PRIVATE KEY\-\-\-\-\- .Ve .IP \(bu 4 X25519 private keys in password protected PEM format .Sp .Vb 3 \& \-\-\-\-\-BEGIN X25519 PRIVATE KEY\-\-\-\-\- \& Proc\-Type: 4,ENCRYPTED \& DEK\-Info: DES\-CBC,DEEFD3D6B714E75A \& \& dfFWP5bKn49aZ993NVAhQQPdFWgsTb4j8CWhRjGBVTPl6ITstAL17deBIRBwZb7h \& pAyIka81Kfs= \& \-\-\-\-\-END X25519 PRIVATE KEY\-\-\-\-\- .Ve .IP \(bu 4 X25519 public keys in PEM format .Sp .Vb 3 \& \-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\- \& MCowBQYDK2VuAyEA6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE= \& \-\-\-\-\-END PUBLIC KEY\-\-\-\-\- .Ve .IP \(bu 4 PKCS#8 private keys .Sp .Vb 3 \& \-\-\-\-\-BEGIN PRIVATE KEY\-\-\-\-\- \& MC4CAQAwBQYDK2VuBCIEIAAvk9ELpXKNjdjpUnch2royYcC7G+/ee0u9rGMdRUZR \& \-\-\-\-\-END PRIVATE KEY\-\-\-\-\- .Ve .IP \(bu 4 PKCS#8 encrypted private keys .Sp .Vb 5 \& \-\-\-\-\-BEGIN ENCRYPTED PRIVATE KEY\-\-\-\-\- \& MIGHMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAiS0NOFZmjJswICCAAw \& DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIGd40Hdso8Y4EONSRCTrqvftl9hl3zbH9 \& 2QmHF1KJ4HDMdLDRxD7EynonCw2SV7BO+XNRHzw2yONqiTybfte7nk9t \& \-\-\-\-\-END ENCRYPTED PRIVATE KEY\-\-\-\-\- .Ve .IP \(bu 4 X25519 private keys in JSON Web Key (JWK) format .Sp See .Sp .Vb 6 \& { \& "kty":"OKP", \& "crv":"X25519", \& "x":"6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE", \& "d":"AC\-T0Qulco2N2OlSdyHaujJhwLsb7957S72sYx1FRlE", \& } .Ve .Sp \&\fBBEWARE:\fR For JWK support you need to have JSON module installed. .IP \(bu 4 X25519 public keys in JSON Web Key (JWK) format .Sp .Vb 5 \& { \& "kty":"OKP", \& "crv":"X25519", \& "x":"6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE", \& } .Ve .Sp \&\fBBEWARE:\fR For JWK support you need to have JSON module installed. .SS import_key_raw .IX Subsection "import_key_raw" Import raw public/private key \- can load raw key data exported by "export_key_raw". .PP .Vb 2 \& $pk\->import_key_raw($key, \*(Aqpublic\*(Aq); \& $pk\->import_key_raw($key, \*(Aqprivate\*(Aq); .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 3 \& my $private_pem = $pk\->export_key_pem(\*(Aqprivate\*(Aq); \& #or \& my $public_pem = $pk\->export_key_pem(\*(Aqpublic\*(Aq); .Ve .PP Support for password protected PEM 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 export_key_jwk .IX Subsection "export_key_jwk" Exports public/private keys as a JSON Web Key (JWK). .PP .Vb 3 \& my $private_json_text = $pk\->export_key_jwk(\*(Aqprivate\*(Aq); \& #or \& my $public_json_text = $pk\->export_key_jwk(\*(Aqpublic\*(Aq); .Ve .PP Also exports public/private keys as a perl HASH with JWK structure. .PP .Vb 3 \& my $jwk_hash = $pk\->export_key_jwk(\*(Aqprivate\*(Aq, 1); \& #or \& my $jwk_hash = $pk\->export_key_jwk(\*(Aqpublic\*(Aq, 1); .Ve .PP \&\fBBEWARE:\fR For JWK support you need to have JSON module installed. .SS export_key_raw .IX Subsection "export_key_raw" Export raw public/private key .PP .Vb 3 \& my $private_bytes = $pk\->export_key_raw(\*(Aqprivate\*(Aq); \& #or \& my $public_bytes = $pk\->export_key_raw(\*(Aqpublic\*(Aq); .Ve .SS shared_secret .IX Subsection "shared_secret" .Vb 4 \& # Alice having her priv key $pk and Bob\*(Aqs public key $pkb \& my $pk = Crypt::PK::X25519\->new($priv_key_filename); \& my $pkb = Crypt::PK::X25519\->new($pub_key_filename); \& my $shared_secret = $pk\->shared_secret($pkb); \& \& # Bob having his priv key $pk and Alice\*(Aqs public key $pka \& my $pk = Crypt::PK::X25519\->new($priv_key_filename); \& my $pka = Crypt::PK::X25519\->new($pub_key_filename); \& my $shared_secret = $pk\->shared_secret($pka); # same value as computed by Alice .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 key2hash .IX Subsection "key2hash" .Vb 1 \& my $hash = $pk\->key2hash; \& \& # returns hash like this (or undef if no key loaded): \& { \& curve => "x25519", \& # raw public key as a hexadecimal string \& pub => "EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41", \& # raw private key as a hexadecimal string. undef if key is public only \& priv => "002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651", \& } .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" .IP \(bu 4 .IP \(bu 4