.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" 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::Ed25519 3pm" .TH Crypt::PK::Ed25519 3pm "2020-11-09" "perl v5.32.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::Ed25519 \- Digital signature based on Ed25519 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Crypt::PK::Ed25519; \& \& #Signature: Alice \& my $priv = Crypt::PK::Ed25519\->new(\*(AqAlice_priv_ed25519.der\*(Aq); \& my $sig = $priv\->sign_message($message); \& \& #Signature: Bob (received $message + $sig) \& my $pub = Crypt::PK::Ed25519\->new(\*(AqAlice_pub_ed25519.der\*(Aq); \& $pub\->verify_message($sig, $message) or die "ERROR"; \& \& #Load key \& my $pk = Crypt::PK::Ed25519\->new; \& my $pk_hex = "A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D"; \& $pk\->import_key_raw(pack("H*", $pk_hex), "public"); \& my $sk = Crypt::PK::Ed25519\->new; \& my $sk_hex = "45C109BA6FD24E8B67D23EFB6B92D99CD457E2137172C0D749FE2B5A0C142DAD"; \& $sk\->import_key_raw(pack("H*", $sk_hex), "private"); \& \& #Key generation \& my $pk = Crypt::PK::Ed25519\->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::Ed25519\->new(); \& #or \& my $pk = Crypt::PK::Ed25519\->new($priv_or_pub_key_filename); \& #or \& my $pk = Crypt::PK::Ed25519\->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::Ed25519\->new($priv_pem_key_filename, $password); \& #or \& my $pk = Crypt::PK::Ed25519\->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 1 \& $pk\->generate_key; .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($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 => "ed25519", \& pub => "A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D", \& priv => "45C109BA6FD24E8B67D23EFB6B92D99CD457E2137172C0D749FE2B5A0C142DAD", \& }); \& \& # or a hash with items corresponding to JWK (JSON Web Key) \& $pk\->import_key({ \& kty => "OKP", \& crv => "Ed25519", \& d => "RcEJum_STotn0j77a5LZnNRX4hNxcsDXSf4rWgwULa0", \& x => "oF0a6lgwrJplzfs4RmDUl\-NpfEa0Gc8s7IXei9JFRZ0", \& }); .Ve .PP Supported key formats: .PP .Vb 2 \& # all formats can be loaded from a file \& my $pk = Crypt::PK::Ed25519\->new($filename); \& \& # or from a buffer containing the key \& my $pk = Crypt::PK::Ed25519\->new(\e$buffer_with_key); .Ve .IP "\(bu" 4 Ed25519 private keys in \s-1PEM\s0 format .Sp .Vb 3 \& \-\-\-\-\-BEGIN ED25519 PRIVATE KEY\-\-\-\-\- \& MC4CAQAwBQYDK2VwBCIEIEXBCbpv0k6LZ9I++2uS2ZzUV+ITcXLA10n+K1oMFC2t \& \-\-\-\-\-END ED25519 PRIVATE KEY\-\-\-\-\- .Ve .IP "\(bu" 4 Ed25519 private keys in password protected \s-1PEM\s0 format .Sp .Vb 3 \& \-\-\-\-\-BEGIN ED25519 PRIVATE KEY\-\-\-\-\- \& Proc\-Type: 4,ENCRYPTED \& DEK\-Info: DES\-CBC,6A64D756D49C1EFF \& \& 8xQ7OyfQ10IITNEKcJGZA53Z1yk+NJQU7hrKqXwChZtgWNInhMBJRl9pozLKDSkH \& v7u6EOve8NY= \& \-\-\-\-\-END ED25519 PRIVATE KEY\-\-\-\-\- .Ve .IP "\(bu" 4 PKCS#8 private keys .Sp .Vb 3 \& \-\-\-\-\-BEGIN PRIVATE KEY\-\-\-\-\- \& MC4CAQAwBQYDK2VwBCIEIEXBCbpv0k6LZ9I++2uS2ZzUV+ITcXLA10n+K1oMFC2t \& \-\-\-\-\-END PRIVATE KEY\-\-\-\-\- .Ve .IP "\(bu" 4 PKCS#8 encrypted private keys .Sp .Vb 5 \& \-\-\-\-\-BEGIN ENCRYPTED PRIVATE KEY\-\-\-\-\- \& MIGHMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjPx9JkdpRH2QICCAAw \& DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIWWieQojaWTcEOGj43SxqHUys4Eb2M27N \& AkhqpmhosOxKrpGi0L3h8m8ipHE8EwI94NeOMsjfVw60aJuCrssY5vKN \& \-\-\-\-\-END ENCRYPTED PRIVATE KEY\-\-\-\-\- .Ve .IP "\(bu" 4 Ed25519 public keys in \s-1PEM\s0 format .Sp .Vb 3 \& \-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\- \& MCowBQYDK2VwAyEAoF0a6lgwrJplzfs4RmDUl+NpfEa0Gc8s7IXei9JFRZ0= \& \-\-\-\-\-END PUBLIC KEY\-\-\-\-\- .Ve .IP "\(bu" 4 Ed25519 public key from X509 certificate .Sp .Vb 9 \& \-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\- \& MIIBODCB66ADAgECAhRWDU9FZBBUZ7KTdX8f7Bco8jsoaTAFBgMrZXAwETEPMA0G \& A1UEAwwGQ3J5cHRYMCAXDTIwMDExOTEzMDIwMloYDzIyOTMxMTAyMTMwMjAyWjAR \& MQ8wDQYDVQQDDAZDcnlwdFgwKjAFBgMrZXADIQCgXRrqWDCsmmXN+zhGYNSX42l8 \& RrQZzyzshd6L0kVFnaNTMFEwHQYDVR0OBBYEFHCGFtVibAxxWYyRt5wazMpqSZDV \& MB8GA1UdIwQYMBaAFHCGFtVibAxxWYyRt5wazMpqSZDVMA8GA1UdEwEB/wQFMAMB \& Af8wBQYDK2VwA0EAqG/+98smzqF/wmFX3zHXSaA67as202HnBJod1Tiurw1f+lr3 \& BX6OMtsDpgRq9O77IF1Qyx/MdJEwwErczOIbAA== \& \-\-\-\-\-END CERTIFICATE\-\-\-\-\- .Ve .IP "\(bu" 4 \&\s-1SSH\s0 public Ed25519 keys .Sp .Vb 1 \& ssh\-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0XsiFcRDp6Hpsoak8OdiiBMJhM2UKszNTxoGS7dJ++ .Ve .IP "\(bu" 4 \&\s-1SSH\s0 public Ed25519 keys (\s-1RFC\-4716\s0 format) .Sp .Vb 4 \& \-\-\-\- BEGIN SSH2 PUBLIC KEY \-\-\-\- \& Comment: "256\-bit ED25519, converted from OpenSSH" \& AAAAC3NzaC1lZDI1NTE5AAAAIL0XsiFcRDp6Hpsoak8OdiiBMJhM2UKszNTxoGS7dJ++ \& \-\-\-\- END SSH2 PUBLIC KEY \-\-\-\- .Ve .IP "\(bu" 4 Ed25519 private keys in \s-1JSON\s0 Web Key (\s-1JWK\s0) format .Sp See .Sp .Vb 6 \& { \& "kty":"OKP", \& "crv":"Ed25519", \& "x":"oF0a6lgwrJplzfs4RmDUl\-NpfEa0Gc8s7IXei9JFRZ0", \& "d":"RcEJum_STotn0j77a5LZnNRX4hNxcsDXSf4rWgwULa0", \& } .Ve .Sp \&\fB\s-1BEWARE:\s0\fR For \s-1JWK\s0 support you need to have \s-1JSON::PP\s0, \s-1JSON::XS\s0 or Cpanel::JSON::XS module. .IP "\(bu" 4 Ed25519 public keys in \s-1JSON\s0 Web Key (\s-1JWK\s0) format .Sp .Vb 5 \& { \& "kty":"OKP", \& "crv":"Ed25519", \& "x":"oF0a6lgwrJplzfs4RmDUl\-NpfEa0Gc8s7IXei9JFRZ0", \& } .Ve .Sp \&\fB\s-1BEWARE:\s0\fR For \s-1JWK\s0 support you need to have \s-1JSON::PP\s0, \s-1JSON::XS\s0 or Cpanel::JSON::XS module. .SS "import_key_raw" .IX Subsection "import_key_raw" Import raw public/private key \- can load raw key data exported by \*(L"export_key_raw\*(R". .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 \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 "export_key_jwk" .IX Subsection "export_key_jwk" Exports public/private keys as a \s-1JSON\s0 Web Key (\s-1JWK\s0). .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 \s-1HASH\s0 with \s-1JWK\s0 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 \&\fB\s-1BEWARE:\s0\fR For \s-1JWK\s0 support you need to have \s-1JSON::PP\s0, \s-1JSON::XS\s0 or Cpanel::JSON::XS module. .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 "sign_message" .IX Subsection "sign_message" .Vb 1 \& my $signature = $priv\->sign_message($message); .Ve .SS "verify_message" .IX Subsection "verify_message" .Vb 1 \& my $valid = $pub\->verify_message($signature, $message) .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 => "ed25519", \& # raw public key as a hexadecimal string \& pub => "A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D", \& # raw private key as a hexadecimal string. undef if key is public only \& priv => "45C109BA6FD24E8B67D23EFB6B92D99CD457E2137172C0D749FE2B5A0C142DAD", \& } .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 .IP "\(bu" 4 .IP "\(bu" 4