File Coverage

blib/lib/Crypt/PK/RSA.pm
Criterion Covered Total %
statement 88 125 70.4
branch 50 104 48.0
condition 10 67 14.9
subroutine 16 19 84.2
pod 11 11 100.0
total 175 326 53.6


line stmt bran cond sub pod time code
1             package Crypt::PK::RSA;
2              
3 7     7   416126 use strict;
  7         87  
  7         207  
4 7     7   41 use warnings;
  7         14  
  7         893  
5             our $VERSION = '0.080_001';
6              
7             require Exporter; our @ISA = qw(Exporter); ### use Exporter 5.57 'import';
8             our %EXPORT_TAGS = ( all => [qw(rsa_encrypt rsa_decrypt rsa_sign_message rsa_verify_message rsa_sign_hash rsa_verify_hash)] );
9             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
10             our @EXPORT = qw();
11              
12 7     7   52 use Carp;
  7         13  
  7         530  
13             $Carp::Internal{(__PACKAGE__)}++;
14 7     7   2506 use CryptX;
  7         15  
  7         252  
15 7     7   2714 use Crypt::Digest qw(digest_data digest_data_b64u);
  7         14  
  7         459  
16 7     7   2768 use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem);
  7         18  
  7         587  
17 7     7   2418 use Crypt::PK;
  7         22  
  7         15182  
18              
19             sub new {
20 107     107 1 455923 my $self = shift->_new();
21 107 100       1501 return @_ > 0 ? $self->import_key(@_) : $self;
22             }
23              
24             sub export_key_pem {
25 3     3 1 575311 my ($self, $type, $password, $cipher) = @_;
26 3         19 local $SIG{__DIE__} = \&CryptX::_croak;
27 3   50     173 my $key = $self->export_key_der($type||'');
28 3 50       10 return unless $key;
29              
30             # PKCS#1 RSAPrivateKey** (PEM header: BEGIN RSA PRIVATE KEY)
31             # PKCS#8 PrivateKeyInfo* (PEM header: BEGIN PRIVATE KEY)
32             # PKCS#8 EncryptedPrivateKeyInfo** (PEM header: BEGIN ENCRYPTED PRIVATE KEY)
33 3 100       14 return der_to_pem($key, "RSA PRIVATE KEY", $password, $cipher) if $type eq 'private';
34              
35             # PKCS#1 RSAPublicKey* (PEM header: BEGIN RSA PUBLIC KEY)
36 2 100       9 return der_to_pem($key, "RSA PUBLIC KEY") if $type eq 'public';
37             # X.509 SubjectPublicKeyInfo** (PEM header: BEGIN PUBLIC KEY)
38 1 50       7 return der_to_pem($key, "PUBLIC KEY") if $type eq 'public_x509';
39             }
40              
41             sub export_key_jwk {
42 0     0 1 0 my ($self, $type, $wanthash) = @_;
43 0         0 local $SIG{__DIE__} = \&CryptX::_croak;
44 0         0 my $kh = $self->key2hash;
45 0 0       0 if ($type eq 'private') {
    0          
46 0 0 0     0 return unless $kh->{N} && $kh->{e} && $kh->{d} && $kh->{p} && $kh->{q} && $kh->{dP} && $kh->{dQ} && $kh->{qP};
      0        
      0        
      0        
      0        
      0        
      0        
47 0         0 for (qw/N e d p q dP dQ qP/) {
48 0 0       0 $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2;
49             }
50             my $hash = {
51             kty => "RSA",
52             n => encode_b64u(pack("H*", $kh->{N})),
53             e => encode_b64u(pack("H*", $kh->{e})),
54             d => encode_b64u(pack("H*", $kh->{d})),
55             p => encode_b64u(pack("H*", $kh->{p})),
56             q => encode_b64u(pack("H*", $kh->{q})),
57             dp => encode_b64u(pack("H*", $kh->{dP})),
58             dq => encode_b64u(pack("H*", $kh->{dQ})),
59 0         0 qi => encode_b64u(pack("H*", $kh->{qP})),
60             };
61 0 0       0 return $wanthash ? $hash : CryptX::_encode_json($hash);
62             }
63             elsif ($type eq 'public') {
64 0 0 0     0 return unless $kh->{N} && $kh->{e};
65 0         0 for (qw/N e/) {
66 0 0       0 $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2;
67             }
68             my $hash = {
69             kty => "RSA",
70             n => encode_b64u(pack("H*", $kh->{N})),
71 0         0 e => encode_b64u(pack("H*", $kh->{e})),
72             };
73 0 0       0 return $wanthash ? $hash : CryptX::_encode_json($hash);
74             }
75             }
76              
77             sub export_key_jwk_thumbprint {
78 0     0 1 0 my ($self, $hash_name) = @_;
79 0         0 local $SIG{__DIE__} = \&CryptX::_croak;
80 0   0     0 $hash_name ||= 'SHA256';
81 0         0 my $h = $self->export_key_jwk('public', 1);
82 0         0 my $json = CryptX::_encode_json({kty=>$h->{kty}, n=>$h->{n}, e=>$h->{e}});
83 0         0 return digest_data_b64u($hash_name, $json);
84             }
85              
86             sub import_key {
87 144     144 1 96903 my ($self, $key, $password) = @_;
88 144         734 local $SIG{__DIE__} = \&CryptX::_croak;
89 144 50       457 croak "FATAL: undefined key" unless $key;
90              
91             # special case
92 144 100       384 if (ref($key) eq 'HASH') {
93 1 50 33     10 if ($key->{N} && $key->{e}) {
94             # hash exported via key2hash
95 1         116 return $self->_import_hex($key->{N}, $key->{e}, $key->{d}, $key->{p}, $key->{q}, $key->{dP}, $key->{dQ}, $key->{qP});
96             }
97 0 0 0     0 if ($key->{n} && $key->{e} && $key->{kty} && $key->{kty} eq "RSA") {
      0        
      0        
98 0         0 $key = {%$key}; #make a copy so that the modifications below stay local
99              
100             # hash with items corresponding to JSON Web Key (JWK)
101 0         0 for (qw/n e d p q dp dq qi/) {
102 0 0       0 $key->{$_} = eval { unpack("H*", decode_b64u($key->{$_})) } if exists $key->{$_};
  0         0  
103             }
104 0         0 return $self->_import_hex($key->{n}, $key->{e}, $key->{d}, $key->{p}, $key->{q}, $key->{dp}, $key->{dq}, $key->{qi});
105             }
106 0         0 croak "FATAL: unexpected RSA key hash";
107             }
108              
109 143         210 my $data;
110 143 100       1675 if (ref($key) eq 'SCALAR') {
    50          
111 72         131 $data = $$key;
112             }
113             elsif (-f $key) {
114 71         314 $data = read_rawfile($key);
115             }
116             else {
117 0         0 croak "FATAL: non-existing file '$key'";
118             }
119 143 50       409 croak "FATAL: invalid key data" unless $data;
120              
121 143 100       1529 if ($data =~ /-----BEGIN (RSA PRIVATE|RSA PUBLIC|PUBLIC) KEY-----(.*?)-----END/sg) {
    100          
    100          
    50          
    100          
    100          
    100          
122             # PKCS#1 RSAPublicKey (PEM header: BEGIN RSA PUBLIC KEY)
123             # PKCS#1 RSAPrivateKey (PEM header: BEGIN RSA PRIVATE KEY)
124             # X.509 SubjectPublicKeyInfo (PEM header: BEGIN PUBLIC KEY)
125 39 50       128 $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed";
126 39 50       4161 return $self->_import($data) if $data;
127             }
128             elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) {
129             # PKCS#8 PrivateKeyInfo (PEM header: BEGIN PRIVATE KEY)
130 1 50       6 $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed";
131 1         82 return $self->_import_pkcs8($data, $password);
132             }
133             elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) {
134             # PKCS#8 PrivateKeyInfo (PEM header: BEGIN ENCRYPTED PRIVATE KEY)
135 1 50       6 $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed";
136 1         3590 return $self->_import_pkcs8($data, $password);
137             }
138             elsif ($data =~ /^\s*(\{.*?\})\s*$/s) {
139             # JSON Web Key (JWK) - http://tools.ietf.org/html/draft-ietf-jose-json-web-key
140 0         0 my $json = "$1";
141 0         0 my $h = CryptX::_decode_json($json);
142 0 0 0     0 if ($h && $h->{kty} eq "RSA") {
143 0         0 for (qw/n e d p q dp dq qi/) {
144 0 0       0 $h->{$_} = eval { unpack("H*", decode_b64u($h->{$_})) } if exists $h->{$_};
  0         0  
145             }
146 0 0 0     0 return $self->_import_hex($h->{n}, $h->{e}, $h->{d}, $h->{p}, $h->{q}, $h->{dp}, $h->{dq}, $h->{qi}) if $h->{n} && $h->{e};
147             }
148             }
149             elsif ($data =~ /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/sg) {
150 1 50       5 $data = pem_to_der($data) or croak "FATAL: PEM/cert decode failed";
151 1         97 return $self->_import_x509($data);
152             }
153             elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) {
154 6 50       23 $data = pem_to_der($data) or croak "FATAL: PEM/key decode failed";
155 6         32 my ($typ, $N, $e) = Crypt::PK::_ssh_parse($data);
156 6 50 33     1810 return $self->_import_hex(unpack("H*", $e), unpack("H*", $N)) if $typ && $e && $N && $typ eq 'ssh-rsa';
      33        
      33        
157             }
158             elsif ($data =~ /ssh-rsa\s+(\S+)/) {
159 6         57 $data = decode_b64("$1");
160 6         22 my ($typ, $N, $e) = Crypt::PK::_ssh_parse($data);
161 6 50 33     1855 return $self->_import_hex(unpack("H*", $e), unpack("H*", $N)) if $typ && $e && $N && $typ eq 'ssh-rsa';
      33        
      33        
162             }
163             else {
164             # DER format
165 89   66     158 my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data, $password) } || eval { $self->_import_x509($data) };
166 89 50       557 return $rv if $rv;
167             }
168              
169 0         0 croak "FATAL: invalid or unsupported RSA key format";
170             }
171              
172             ### FUNCTIONS
173              
174             sub rsa_encrypt {
175 1     1 1 313 my $key = shift;
176 1         6 local $SIG{__DIE__} = \&CryptX::_croak;
177 1 50       7 $key = __PACKAGE__->new($key) unless ref $key;
178 1 50       6 carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__;
179 1         178 return $key->encrypt(@_);
180             }
181              
182             sub rsa_decrypt {
183 1     1 1 311 my $key = shift;
184 1         7 local $SIG{__DIE__} = \&CryptX::_croak;
185 1 50       9 $key = __PACKAGE__->new($key) unless ref $key;
186 1 50       7 carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__;
187 1         5197 return $key->decrypt(@_);
188             }
189              
190             sub rsa_sign_hash {
191 1     1 1 3 my $key = shift;
192 1         5 local $SIG{__DIE__} = \&CryptX::_croak;
193 1 50       11 $key = __PACKAGE__->new($key) unless ref $key;
194 1 50       6 carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__;
195 1         5427 return $key->sign_hash(@_);
196             }
197              
198             sub rsa_verify_hash {
199 1     1 1 351 my $key = shift;
200 1         6 local $SIG{__DIE__} = \&CryptX::_croak;
201 1 50       10 $key = __PACKAGE__->new($key) unless ref $key;
202 1 50       7 carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__;
203 1         236 return $key->verify_hash(@_);
204             }
205              
206             sub rsa_sign_message {
207 1     1 1 366 my $key = shift;
208 1         7 local $SIG{__DIE__} = \&CryptX::_croak;
209 1 50       9 $key = __PACKAGE__->new($key) unless ref $key;
210 1 50       5 carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__;
211 1         5245 return $key->sign_message(@_);
212             }
213              
214             sub rsa_verify_message {
215 1     1 1 367 my $key = shift;
216 1         7 local $SIG{__DIE__} = \&CryptX::_croak;
217 1 50       10 $key = __PACKAGE__->new($key) unless ref $key;
218 1 50       6 carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__;
219 1         241 return $key->verify_message(@_);
220             }
221              
222 0     0     sub CLONE_SKIP { 1 } # prevent cloning
223              
224             1;
225              
226             =pod
227              
228             =head1 NAME
229              
230             Crypt::PK::RSA - Public key cryptography based on RSA
231              
232             =head1 SYNOPSIS
233              
234             ### OO interface
235              
236             #Encryption: Alice
237             my $pub = Crypt::PK::RSA->new('Bob_pub_rsa1.der');
238             my $ct = $pub->encrypt("secret message");
239             #
240             #Encryption: Bob (received ciphertext $ct)
241             my $priv = Crypt::PK::RSA->new('Bob_priv_rsa1.der');
242             my $pt = $priv->decrypt($ct);
243              
244             #Signature: Alice
245             my $priv = Crypt::PK::RSA->new('Alice_priv_rsa1.der');
246             my $sig = $priv->sign_message($message);
247             #
248             #Signature: Bob (received $message + $sig)
249             my $pub = Crypt::PK::RSA->new('Alice_pub_rsa1.der');
250             $pub->verify_message($sig, $message) or die "ERROR";
251              
252             #Key generation
253             my $pk = Crypt::PK::RSA->new();
254             $pk->generate_key(256, 65537);
255             my $private_der = $pk->export_key_der('private');
256             my $public_der = $pk->export_key_der('public');
257             my $private_pem = $pk->export_key_pem('private');
258             my $public_pem = $pk->export_key_pem('public');
259              
260             ### Functional interface
261              
262             #Encryption: Alice
263             my $ct = rsa_encrypt('Bob_pub_rsa1.der', "secret message");
264             #Encryption: Bob (received ciphertext $ct)
265             my $pt = rsa_decrypt('Bob_priv_rsa1.der', $ct);
266              
267             #Signature: Alice
268             my $sig = rsa_sign_message('Alice_priv_rsa1.der', $message);
269             #Signature: Bob (received $message + $sig)
270             rsa_verify_message('Alice_pub_rsa1.der', $sig, $message) or die "ERROR";
271              
272             =head1 DESCRIPTION
273              
274             The module provides a full featured RSA implementation.
275              
276             =head1 METHODS
277              
278             =head2 new
279              
280             my $pk = Crypt::PK::RSA->new();
281             #or
282             my $pk = Crypt::PK::RSA->new($priv_or_pub_key_filename);
283             #or
284             my $pk = Crypt::PK::RSA->new(\$buffer_containing_priv_or_pub_key);
285              
286             Support for password protected PEM keys
287              
288             my $pk = Crypt::PK::RSA->new($priv_pem_key_filename, $password);
289             #or
290             my $pk = Crypt::PK::RSA->new(\$buffer_containing_priv_pem_key, $password);
291              
292             =head2 generate_key
293              
294             Uses Yarrow-based cryptographically strong random number generator seeded with
295             random data taken from C (UNIX) or C (Win32).
296              
297             $pk->generate_key($size, $e);
298             # $size .. key size: 128-512 bytes (DEFAULT is 256)
299             # $e ..... exponent: 3, 17, 257 or 65537 (DEFAULT is 65537)
300              
301             =head2 import_key
302              
303             Loads private or public key in DER or PEM format.
304              
305             $pk->import_key($priv_or_pub_key_filename);
306             #or
307             $pk->import_key(\$buffer_containing_priv_or_pub_key);
308              
309             Support for password protected PEM keys
310              
311             $pk->import_key($pem_filename, $password);
312             #or
313             $pk->import_key(\$buffer_containing_pem_key, $password);
314              
315             Loading private or public keys form perl hash:
316              
317             $pk->import_key($hashref);
318              
319             # the $hashref is either a key exported via key2hash
320             $pk->import_key({
321             e => "10001", #public exponent
322             d => "9ED5C3D3F866E06957CA0E9478A273C39BBDA4EEAC5B...", #private exponent
323             N => "D0A5CCCAE03DF9C2F5C4C8C0CE840D62CDE279990DC6...", #modulus
324             p => "D3EF0028FFAB508E2773C659E428A80FB0E9211346B4...", #p factor of N
325             q => "FC07E46B163CAB6A83B8E467D169534B2077DCDEECAE...", #q factor of N
326             qP => "88C6D406F833DF73C8B734548E0385261AD51F4187CF...", #1/q mod p CRT param
327             dP => "486F142FEF0A1F53269AC43D2EE4D263E2841B60DA36...", #d mod (p - 1) CRT param
328             dQ => "4597284B2968B72C4212DB7E8F24360B987B80514DA9...", #d mod (q - 1) CRT param
329             });
330              
331             # or a hash with items corresponding to JWK (JSON Web Key)
332             $pk->import_key({
333             {
334             kty => "RSA",
335             n => "0vx7agoebGcQSuuPiLJXZpt...eZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
336             e => "AQAB",
337             d => "X4cTteJY_gn4FYPsXB8rdXi...FLN5EEaG6RoVH-HLKD9Mdx5ooGURknhnrRwUkC7h5fJLMWbFAKLWY2v7B6NqSzUvx0_YSf",
338             p => "83i-7IvMGXoMXCskv73TKr8...Z27zvoj6pbUQyLPBQxtPnwD20-60eTmD2ujMt5PoMrm8RmNhVWtjjMmMjOpSicFHjXOuVI",
339             q => "3dfOR9cuYq-0S-mkFLzgItg...q3hWeMuG0ouqnb3obLyuqjVZQ1dIrdgTnCdYzBcOW5r37AFXjift_NGiovonzhKpoVVS78",
340             dp => "G4sPXkc6Ya9y8oJW9_ILj4...zi_H7TkS8x5SdX3oE0oiYwxIiemTAu0UOa5pgFGyJ4c8t2VF40XRugKTP8akhFo5tA77Qe",
341             dq => "s9lAH9fggBsoFR8Oac2R_E...T2kGOhvIllTE1efA6huUvMfBcpn8lqW6vzzYY5SSF7pMd_agI3G8IbpBUb0JiraRNUfLhc",
342             qi => "GyM_p6JrXySiz1toFgKbWV...4ypu9bMWx3QJBfm0FoYzUIZEVEcOqwmRN81oDAaaBk0KWGDjJHDdDmFW3AN7I-pux_mHZG",
343             });
344              
345             Supported key formats:
346              
347             # all formats can be loaded from a file
348             my $pk = Crypt::PK::RSA->new($filename);
349              
350             # or from a buffer containing the key
351             my $pk = Crypt::PK::RSA->new(\$buffer_with_key);
352              
353             =over
354              
355             =item * RSA public keys
356              
357             -----BEGIN PUBLIC KEY-----
358             MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHlYKg9DeHB3/dY1D9WCyJTnl5
359             vEzAXpUOL9tDtdPUl96brIbbdMLooO1hKjsq98kLs1q4vOn/pxvzk0BRwhiu7Vvb
360             VUjAn/2HHDDL0U1utqqlMJhaffeLI3HEq5o/lSMFY7sSkZU/E4YX1yqAN0SE7xfK
361             B2uzcNq60sMIfp6siQIDAQAB
362             -----END PUBLIC KEY-----
363              
364             =item * RSA private keys
365              
366             -----BEGIN RSA PRIVATE KEY-----
367             MIICXQIBAAKBgQDHlYKg9DeHB3/dY1D9WCyJTnl5vEzAXpUOL9tDtdPUl96brIbb
368             dMLooO1hKjsq98kLs1q4vOn/pxvzk0BRwhiu7VvbVUjAn/2HHDDL0U1utqqlMJha
369             ffeLI3HEq5o/lSMFY7sSkZU/E4YX1yqAN0SE7xfKB2uzcNq60sMIfp6siQIDAQAB
370             AoGBAI5+GgNcGQDYw9uF+t7FwxZM5sGZRJrbbEPyuvL+sDxKKW6voKCyHi4EJzaF
371             9jRZMDqgVJcsmUwjPPuMGBHHJ+MI5Zb3L0jbZkyx8u+U5gf88oy9eZmfGOjmHcMB
372             oCgzyoLmJETuyADg2onLanuY3jggFb3tq/jimKjO8xM2R6zhAkEA7uXWWyJI9cCN
373             zrVt5R5v6oosjZ4r5VILGMqBRLrzfTvH+WDMK6Rl/2MHE+YDeLajzunaM8qY2456
374             GTYEXQsIdQJBANXfMEtXocSdPtoVj3ME8Do/0r+ApgTdcDPCwXOzkmkEJW/UFMSn
375             b8CYF5G6sZQN9L5z3s2nvi55PaFV8Q0LMUUCQBh9GvIQm6YFbQPpeTBpZFOIgnSp
376             6BoDxPtvlryy5U7LF/6qO4OlwIbjYdBaXbS8FCKbujBg7jZjboSzEtNu1BkCQDGT
377             w0Yz0jQZn3A+fzpScr2N/fSWheWqz0+wXdfMUKw3YdZCe236wlUK7KvDc1a2xX1A
378             ru1NbTCoujikC3TSm2ECQQDKQshchJlZJmFv9vCFQlGCA/EX+4406xvOOiixbPYC
379             pIB4Ee2cmvEdAqSaOjrvgs5zvaCCFBO0MecPStCAxUX6
380             -----END RSA PRIVATE KEY-----
381              
382             =item * RSA private keys in password protected PEM format
383              
384             -----BEGIN RSA PRIVATE KEY-----
385             Proc-Type: 4,ENCRYPTED
386             DEK-Info: DES-EDE3-CBC,4D697440FF5AEF18
387              
388             C09H49Gn99o8b8O2r4+Hqao4r3udvC+QSSfsk20sXatyuZSEmbhyqKAB+13NRj+3
389             KIsRTqnL9VkeibIGgLHuekOFKAqeSVZ0PmR4bGWEFxUPAYUvg9N9pIa6hGtNZG+y
390             TEpOAfFITb1pbHQhp3j8y7qmKc5kY5LrZSFE8WwA24NTG773E07wJgRxKDkXNGOl
391             kki6oYArNEps0DdtHFxzgdRg0+yaotXuFJRuC5V4YzKGG/oSRcgYyXKTwCndb3xt
392             aHgI2WprQAPg+qOpLABzoi7bEjCqbHWrwkvnAngylbim2Uyvw1e1xKnzlgIHU7pv
393             e/J+s00pTItfqW1IpY2mh4C9nkfkfVKBKaAv7jO0s6aPySATqsdlrzv2kpF6Ub4J
394             kgaZDOfZ4K3qkyAYVLWcQeDqg4glv9Ah2J05bTm4qrIMmthYnThyQlGvcjUfCMXs
395             0t+mEQbsRY7xKt0o6HzzvQlJ+JsFlLORoslAubJX9iLqpEdnlrj1lD9bo6uIClZ5
396             5+aoLcAyz1D4OsauuP5i8VFu+Is+QG4SN/vHVuArjkqi3VpLwSAjNDY+KWbq042l
397             CqlM2mwm6FIGUZQFxiLHJD7WDmk1xmae++m+XG9CEDTfrUQ5v+l0O6BTrl80XUfU
398             w3gzAWbSjz3UK0FpKeABVFPE9fjNP9fTcS6qL5YJWBPflwxCAbVgsBOW4bOMpDGK
399             BJDQTeShWn4BlYCe/vgThI9ERdgZhRz4NcFeDgVA/CqQzVqptvz4PSqH46fqUN2n
400             4PtJgKE5cASYUBuAjlD71FecSVVM/OTzL1uxYzXBilzvVn2vSHgo9g==
401             -----END RSA PRIVATE KEY-----
402              
403             =item * PKCS#8 encoded private keys
404              
405             -----BEGIN PRIVATE KEY-----
406             MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANPN17xW4EkH5PXG
407             1i/i3rE1EXFcCHyxmz95VRBDs1p3MuYf9mxntbfYAmuzS3KrRWh3IyX/Eh80N/v9
408             OXPlwZbVqSTX+L3pCEJtRtsWn0zmswGThjMZiwle0oWuap63L35F1QN8EDaSPSBC
409             yGELNRr6rwVYq0w5b+LOcaCZ+/H1AgMBAAECgYEApfu3aGpww+rC3HUhX0+ckyTy
410             cXLdV9LbxidwqRlVEb0+DyfXNucjelp2sy5EHy3na9GJovo8mmWSxhCRGKliRkQ6
411             XgrEMZdCSaWI2AazuHAGlUJRFEVkvdla3AuBAn6y0YdDp/3kbg0yahmKyD8Gq74z
412             nUYbDL3R5JtR2Ad/KlUCQQDvSEICTHbO/BF7hVmlKRYZSNHKEPrv8X/OlppS14Kv
413             QRwc+CZ5+l6T1Y+l5cHJQUXrXZoWS1K741TXdUhjjUd7AkEA4pod804Ex8sttdWi
414             pHMfeyj+IbPAk5XnBc91jT7AYIeL8ccjtfl99xhMsGFaxrh3wA/4SGEvwzWkbxcq
415             H8G5TwJAKNG+0P2SVwURRm0dOdukdXPCtiHnbP9Zujhe4zr4hEUrMpXymmRntfh8
416             pORpBpgoAVraams3Fe5WDttnGfSD+QJAOOC6V9HjfUrQhG3FT0XeRwm5EDiQQ/tC
417             a8DxHqz7mL8tL1ju68ReC+G7jiJBqNOwqzLW/UP3uyYByiikWChGHQJAHUau7jIM
418             45ErO096n94Vh95p76ANxOroWszOt39TyvJOykIfoPwFagLrBWV9Jjos2/D54KE+
419             fyoy4t3yHT+/nw==
420             -----END PRIVATE KEY-----
421              
422             =item * PKCS#8 encrypted private keys - password protected keys (supported since: CryptX-0.062)
423              
424             -----BEGIN ENCRYPTED PRIVATE KEY-----
425             MIICojAcBgoqhkiG9w0BDAEDMA4ECCQk+Rr1yzzcAgIIAASCAoD/mgpUFjxxM/Ty
426             Yt+NeT0Fo4echgoGksqs6+rYhO16oshG664emZfkuNoFGGzJ38X6GVuqIXhlPnYQ
427             biKvL37dN/KnoGytFHq9Wnk8dDwjGHPtwajhW5WuIV3NuhW/AO1PF/cRZKFjWrPt
428             NWY5CrpfH6t6zojoe+5uyXpH29lQy4OqvSRdPIt/12UcB+tzV7XzSWEuXh8HAi8a
429             sYUu6tuCFnq4GrD2ffM4KWFmL5GqBAwN6m0KkyrNni9XT+RaA6zEhv/lVcwg2esa
430             4/EzRs0ixzzZDKaml8oCMl9RHtFAbQmdlfV7Ip4rGK9BwY6UFiDMIVru6HynOVQK
431             vvZ+j//bgO+3ubrv7psX+vC9Fy/MoH2Tc7MIwDN/QVTciPZlzjWBnBNxMfeFKtEn
432             d7NFiapgfLuRQIiDTMrW/clcqvO54NphxhrcgUEoxos4twKZARntqPZHtf8nEM2x
433             2sEF5kI65aEF/5Yy16qvP0vZAA2B1kcIdXZ8XLZCp4c3olhkIrmgUpo1gyFXdCoC
434             7dT5Cz7/YLkq5hkcFrtp4V9BZMR24fSttc4p24N5xuZ+JneGnGkLX6B+nJAtm9vw
435             bZA6P+23GI0qeMzL3HJXwCOTSsWfm/H9W5+2Zmw851aAmE+pZLni/pk3e3iNSWgs
436             946x/doA5O0uCFsU7oxme+WAIp2SjhxGoe808Lf1CCFMPboFi1O/E0NsX8SIEX+i
437             U+UHi4kxZqVkr3Q5SB/9kiSv8K1bE787yueQOT/dsTYYaMsjAbkEZo0o/47F32T6
438             A2ioXHOV/pr5zNHqE5tL+qKEcLYbAUF1O+WvmdqYz+vHQjRQBatAqTmncvLDYr/j
439             1HPwZX2d
440             -----END ENCRYPTED PRIVATE KEY-----
441              
442             =item * RSA public key from X509 certificate
443              
444             -----BEGIN CERTIFICATE-----
445             MIIC8zCCAdugAwIBAgIJAPi+LvMU3uGWMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNV
446             BAMMBXBva3VzMB4XDTE3MDcxNDE0MTAyMFoXDTIwMDQwOTE0MTAyMFowEDEOMAwG
447             A1UEAwwFcG9rdXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCQima
448             SUIMIdz5uVevzcScbcj06xs1OLaFKUoPJ8v+xP6Ut61BQhAvc8GYuw2uRx223hZC
449             r3HYLfSdWIfmOIAtlL8cPYPVoSivJtpSGE6fBG1tlBjVgXWRmJGR/oxx6Y5QDwcB
450             Q4GZKga8TtHQoY5idZuatYOFZGfMIcIUC0Uoda+YSypnw7A90F/JvlpcTUh3Fnem
451             VinqEA6XOegU9dCZk/29sXqauBjbdGihh8DvpklOhY16eQoiR3909AywQ0KUmI+R
452             Sa9E8oIsmUDetFuXEvana+sD3y42tU+cd2nhBPRETbSXPcum0B3uF4yKgweuJy5D
453             cvtVQIFVkkh4+AWNAgMBAAGjUDBOMB0GA1UdDgQWBBSS6V5PVGyN92NoB0AVLcOb
454             pzR3SzAfBgNVHSMEGDAWgBSS6V5PVGyN92NoB0AVLcObpzR3SzAMBgNVHRMEBTAD
455             AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBIszrBjoJ39axsS6Btbvwvo8vAmgiSWsav
456             7AmjXOAwknHPaCcDmrdOys5POD0DNRwNeRsnxFiZ/UL8Vmj2JGDLgAw+/v32MwfX
457             Ig7m+oIbO8KqDzlYvS5kd3suJ5C21hHy1/JUtfofZLovZH7ZRzhTAoRvCYaodW90
458             2o8ZqmyCdcXPzjFmoJ2xYzs/Sf8/E1cHfb+4HjOpeRnKxDvG0gwWzcsXpUrw2pNO
459             Oztj6Rd0THNrf/anIeYVtAHX4aqZA8Kbv2TyJd+9g78usFw1cn+8vfmilm6Pn0DQ
460             a+I5GyGd7BJI8wYuWqIStzvrJHbQQaNrSk7hgjWYiYlcsPh6w2QP
461             -----END CERTIFICATE-----
462              
463             =item * SSH public RSA keys
464              
465             ssh-rsa AAAAB3NzaC1yc2EAAAADAQA...6mdYs5iJNGu/ltUdc=
466              
467             =item * SSH public RSA keys (RFC-4716 format)
468              
469             ---- BEGIN SSH2 PUBLIC KEY ----
470             Comment: "768-bit RSA, converted from OpenSSH"
471             AAAAB3NzaC1yc2EAAAADAQABAAAAYQDYebeGQFCnlQiNRE7r9UEbjr+DQMTdw1ZHGB2w6x
472             D/DzKem8761GdCpqsLrGaw2D7aSIoP1B5Sz870YoVWHn6Ao7Hvm17V3Kxfn4B01GNQTM5+
473             L26mdYs5iJNGu/ltUdc=
474             ---- END SSH2 PUBLIC KEY ----
475              
476             =item * RSA private keys in JSON Web Key (JWK) format
477              
478             See L
479              
480             {
481             "kty":"RSA",
482             "n":"0vx7agoebGcQSuuPiLJXZpt...eZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
483             "e":"AQAB",
484             "d":"X4cTteJY_gn4FYPsXB8rdXi...FLN5EEaG6RoVH-HLKD9Mdx5ooGURknhnrRwUkC7h5fJLMWbFAKLWY2v7B6NqSzUvx0_YSf",
485             "p":"83i-7IvMGXoMXCskv73TKr8...Z27zvoj6pbUQyLPBQxtPnwD20-60eTmD2ujMt5PoMrm8RmNhVWtjjMmMjOpSicFHjXOuVI",
486             "q":"3dfOR9cuYq-0S-mkFLzgItg...q3hWeMuG0ouqnb3obLyuqjVZQ1dIrdgTnCdYzBcOW5r37AFXjift_NGiovonzhKpoVVS78",
487             "dp":"G4sPXkc6Ya9y8oJW9_ILj4...zi_H7TkS8x5SdX3oE0oiYwxIiemTAu0UOa5pgFGyJ4c8t2VF40XRugKTP8akhFo5tA77Qe",
488             "dq":"s9lAH9fggBsoFR8Oac2R_E...T2kGOhvIllTE1efA6huUvMfBcpn8lqW6vzzYY5SSF7pMd_agI3G8IbpBUb0JiraRNUfLhc",
489             "qi":"GyM_p6JrXySiz1toFgKbWV...4ypu9bMWx3QJBfm0FoYzUIZEVEcOqwmRN81oDAaaBk0KWGDjJHDdDmFW3AN7I-pux_mHZG",
490             }
491              
492             B For JWK support you need to have L module installed.
493              
494             =item * RSA public keys in JSON Web Key (JWK) format
495              
496             {
497             "kty":"RSA",
498             "n": "0vx7agoebGcQSuuPiLJXZp...tN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECP",
499             "e":"AQAB",
500             }
501              
502             B For JWK support you need to have L module installed.
503              
504             =back
505              
506             =head2 export_key_der
507              
508             my $private_der = $pk->export_key_der('private');
509             #or
510             my $public_der = $pk->export_key_der('public');
511              
512             =head2 export_key_pem
513              
514             my $private_pem = $pk->export_key_pem('private');
515             #or
516             my $public_pem = $pk->export_key_pem('public');
517             #or
518             my $public_pem = $pk->export_key_pem('public_x509');
519              
520             With parameter C<'public'> uses header and footer lines:
521              
522             -----BEGIN RSA PUBLIC KEY------
523             -----END RSA PUBLIC KEY------
524              
525             With parameter C<'public_x509'> uses header and footer lines:
526              
527             -----BEGIN PUBLIC KEY------
528             -----END PUBLIC KEY------
529              
530             Support for password protected PEM keys
531              
532             my $private_pem = $pk->export_key_pem('private', $password);
533             #or
534             my $private_pem = $pk->export_key_pem('private', $password, $cipher);
535              
536             # supported ciphers: 'DES-CBC'
537             # 'DES-EDE3-CBC'
538             # 'SEED-CBC'
539             # 'CAMELLIA-128-CBC'
540             # 'CAMELLIA-192-CBC'
541             # 'CAMELLIA-256-CBC'
542             # 'AES-128-CBC'
543             # 'AES-192-CBC'
544             # 'AES-256-CBC' (DEFAULT)
545              
546             =head2 export_key_jwk
547              
548             I
549              
550             Exports public/private keys as a JSON Web Key (JWK).
551              
552             my $private_json_text = $pk->export_key_jwk('private');
553             #or
554             my $public_json_text = $pk->export_key_jwk('public');
555              
556             Also exports public/private keys as a perl HASH with JWK structure.
557              
558             my $jwk_hash = $pk->export_key_jwk('private', 1);
559             #or
560             my $jwk_hash = $pk->export_key_jwk('public', 1);
561              
562             B For JWK support you need to have L module installed.
563              
564             =head2 export_key_jwk_thumbprint
565              
566             I
567              
568             Exports the key's JSON Web Key Thumbprint as a string.
569              
570             If you don't know what this is, see RFC 7638 L.
571              
572             my $thumbprint = $pk->export_key_jwk_thumbprint('SHA256');
573              
574             =head2 encrypt
575              
576             my $pk = Crypt::PK::RSA->new($pub_key_filename);
577             my $ct = $pk->encrypt($message);
578             #or
579             my $ct = $pk->encrypt($message, $padding);
580             #or
581             my $ct = $pk->encrypt($message, 'oaep', $hash_name, $lparam);
582              
583             # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE)
584             # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
585             # $lparam (only for oaep) ..... DEFAULT is empty string
586              
587             =head2 decrypt
588              
589             my $pk = Crypt::PK::RSA->new($priv_key_filename);
590             my $pt = $pk->decrypt($ciphertext);
591             #or
592             my $pt = $pk->decrypt($ciphertext, $padding);
593             #or
594             my $pt = $pk->decrypt($ciphertext, 'oaep', $hash_name, $lparam);
595              
596             # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE)
597             # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
598             # $lparam (only for oaep) ..... DEFAULT is empty string
599              
600             =head2 sign_message
601              
602             my $pk = Crypt::PK::RSA->new($priv_key_filename);
603             my $signature = $priv->sign_message($message);
604             #or
605             my $signature = $priv->sign_message($message, $hash_name);
606             #or
607             my $signature = $priv->sign_message($message, $hash_name, $padding);
608             #or
609             my $signature = $priv->sign_message($message, $hash_name, 'pss', $saltlen);
610              
611             # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
612             # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE)
613             # $saltlen (only for pss) .. DEFAULT is 12
614              
615             =head2 verify_message
616              
617             my $pk = Crypt::PK::RSA->new($pub_key_filename);
618             my $valid = $pub->verify_message($signature, $message);
619             #or
620             my $valid = $pub->verify_message($signature, $message, $hash_name);
621             #or
622             my $valid = $pub->verify_message($signature, $message, $hash_name, $padding);
623             #or
624             my $valid = $pub->verify_message($signature, $message, $hash_name, 'pss', $saltlen);
625              
626             # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
627             # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE)
628             # $saltlen (only for pss) .. DEFAULT is 12
629              
630             =head2 sign_hash
631              
632             my $pk = Crypt::PK::RSA->new($priv_key_filename);
633             my $signature = $priv->sign_hash($message_hash);
634             #or
635             my $signature = $priv->sign_hash($message_hash, $hash_name);
636             #or
637             my $signature = $priv->sign_hash($message_hash, $hash_name, $padding);
638             #or
639             my $signature = $priv->sign_hash($message_hash, $hash_name, 'pss', $saltlen);
640              
641             # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
642             # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE)
643             # $saltlen (only for pss) .. DEFAULT is 12
644              
645             =head2 verify_hash
646              
647             my $pk = Crypt::PK::RSA->new($pub_key_filename);
648             my $valid = $pub->verify_hash($signature, $message_hash);
649             #or
650             my $valid = $pub->verify_hash($signature, $message_hash, $hash_name);
651             #or
652             my $valid = $pub->verify_hash($signature, $message_hash, $hash_name, $padding);
653             #or
654             my $valid = $pub->verify_hash($signature, $message_hash, $hash_name, 'pss', $saltlen);
655              
656             # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
657             # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE)
658             # $saltlen (only for pss) .. DEFAULT is 12
659              
660             =head2 is_private
661              
662             my $rv = $pk->is_private;
663             # 1 .. private key loaded
664             # 0 .. public key loaded
665             # undef .. no key loaded
666              
667             =head2 size
668              
669             my $size = $pk->size;
670             # returns key size in bytes or undef if no key loaded
671              
672             =head2 key2hash
673              
674             my $hash = $pk->key2hash;
675              
676             # returns hash like this (or undef if no key loaded):
677             {
678             type => 1, # integer: 1 .. private, 0 .. public
679             size => 256, # integer: key size in bytes
680             # all the rest are hex strings
681             e => "10001", #public exponent
682             d => "9ED5C3D3F866E06957CA0E9478A273C39BBDA4EEAC5B...", #private exponent
683             N => "D0A5CCCAE03DF9C2F5C4C8C0CE840D62CDE279990DC6...", #modulus
684             p => "D3EF0028FFAB508E2773C659E428A80FB0E9211346B4...", #p factor of N
685             q => "FC07E46B163CAB6A83B8E467D169534B2077DCDEECAE...", #q factor of N
686             qP => "88C6D406F833DF73C8B734548E0385261AD51F4187CF...", #1/q mod p CRT param
687             dP => "486F142FEF0A1F53269AC43D2EE4D263E2841B60DA36...", #d mod (p - 1) CRT param
688             dQ => "4597284B2968B72C4212DB7E8F24360B987B80514DA9...", #d mod (q - 1) CRT param
689             }
690              
691             =head1 FUNCTIONS
692              
693             =head2 rsa_encrypt
694              
695             RSA based encryption. See method L below.
696              
697             my $ct = rsa_encrypt($pub_key_filename, $message);
698             #or
699             my $ct = rsa_encrypt(\$buffer_containing_pub_key, $message);
700             #or
701             my $ct = rsa_encrypt($pub_key, $message, $padding);
702             #or
703             my $ct = rsa_encrypt($pub_key, $message, 'oaep', $hash_name, $lparam);
704              
705             # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE)
706             # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
707             # $lparam (only for oaep) ..... DEFAULT is empty string
708              
709             =head2 rsa_decrypt
710              
711             RSA based decryption. See method L below.
712              
713             my $pt = rsa_decrypt($priv_key_filename, $ciphertext);
714             #or
715             my $pt = rsa_decrypt(\$buffer_containing_priv_key, $ciphertext);
716             #or
717             my $pt = rsa_decrypt($priv_key, $ciphertext, $padding);
718             #or
719             my $pt = rsa_decrypt($priv_key, $ciphertext, 'oaep', $hash_name, $lparam);
720              
721             # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE)
722             # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
723             # $lparam (only for oaep) ..... DEFAULT is empty string
724              
725             =head2 rsa_sign_message
726              
727             Generate RSA signature. See method L below.
728              
729             my $sig = rsa_sign_message($priv_key_filename, $message);
730             #or
731             my $sig = rsa_sign_message(\$buffer_containing_priv_key, $message);
732             #or
733             my $sig = rsa_sign_message($priv_key, $message, $hash_name);
734             #or
735             my $sig = rsa_sign_message($priv_key, $message, $hash_name, $padding);
736             #or
737             my $sig = rsa_sign_message($priv_key, $message, $hash_name, 'pss', $saltlen);
738              
739             # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
740             # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE)
741             # $saltlen (only for pss) .. DEFAULT is 12
742              
743             =head2 rsa_verify_message
744              
745             Verify RSA signature. See method L below.
746              
747             rsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
748             #or
749             rsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
750             #or
751             rsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
752             #or
753             rsa_verify_message($pub_key, $signature, $message, $hash_name, $padding) or die "ERROR";
754             #or
755             rsa_verify_message($pub_key, $signature, $message, $hash_name, 'pss', $saltlen) or die "ERROR";
756              
757             # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
758             # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE)
759             # $saltlen (only for pss) .. DEFAULT is 12
760              
761             =head2 rsa_sign_hash
762              
763             Generate RSA signature. See method L below.
764              
765             my $sig = rsa_sign_hash($priv_key_filename, $message_hash);
766             #or
767             my $sig = rsa_sign_hash(\$buffer_containing_priv_key, $message_hash);
768             #or
769             my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name);
770             #or
771             my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, $padding);
772             #or
773             my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, 'pss', $saltlen);
774              
775             # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
776             # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE)
777             # $saltlen (only for pss) .. DEFAULT is 12
778              
779             =head2 rsa_verify_hash
780              
781             Verify RSA signature. See method L below.
782              
783             rsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
784             #or
785             rsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
786             #or
787             rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name) or die "ERROR";
788             #or
789             rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, $padding) or die "ERROR";
790             #or
791             rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, 'pss', $saltlen) or die "ERROR";
792              
793             # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
794             # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE)
795             # $saltlen (only for pss) .. DEFAULT is 12
796              
797             =head1 OpenSSL interoperability
798              
799             ### let's have:
800             # RSA private key in PEM format - rsakey.priv.pem
801             # RSA public key in PEM format - rsakey.pub.pem
802             # data file to be signed or encrypted - input.data
803              
804             =head2 Encrypt by OpenSSL, decrypt by Crypt::PK::RSA
805              
806             Create encrypted file (from commandline):
807              
808             openssl rsautl -encrypt -inkey rsakey.pub.pem -pubin -out input.encrypted.rsa -in input.data
809              
810             Decrypt file (Perl code):
811              
812             use Crypt::PK::RSA;
813             use Crypt::Misc 'read_rawfile';
814              
815             my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem");
816             my $encfile = read_rawfile("input.encrypted.rsa");
817             my $plaintext = $pkrsa->decrypt($encfile, 'v1.5');
818             print $plaintext;
819              
820             =head2 Encrypt by Crypt::PK::RSA, decrypt by OpenSSL
821              
822             Create encrypted file (Perl code):
823              
824             use Crypt::PK::RSA;
825             use Crypt::Misc 'write_rawfile';
826              
827             my $plaintext = 'secret message';
828             my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem");
829             my $encrypted = $pkrsa->encrypt($plaintext, 'v1.5');
830             write_rawfile("input.encrypted.rsa", $encrypted);
831              
832             Decrypt file (from commandline):
833              
834             openssl rsautl -decrypt -inkey rsakey.priv.pem -in input.encrypted.rsa
835              
836             =head2 Sign by OpenSSL, verify by Crypt::PK::RSA
837              
838             Create signature (from commandline):
839              
840             openssl dgst -sha1 -sign rsakey.priv.pem -out input.sha1-rsa.sig input.data
841              
842             Verify signature (Perl code):
843              
844             use Crypt::PK::RSA;
845             use Crypt::Digest 'digest_file';
846             use Crypt::Misc 'read_rawfile';
847              
848             my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem");
849             my $signature = read_rawfile("input.sha1-rsa.sig");
850             my $valid = $pkrsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5");
851             print $valid ? "SUCCESS" : "FAILURE";
852              
853             =head2 Sign by Crypt::PK::RSA, verify by OpenSSL
854              
855             Create signature (Perl code):
856              
857             use Crypt::PK::RSA;
858             use Crypt::Digest 'digest_file';
859             use Crypt::Misc 'write_rawfile';
860              
861             my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem");
862             my $signature = $pkrsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5");
863             write_rawfile("input.sha1-rsa.sig", $signature);
864              
865             Verify signature (from commandline):
866              
867             openssl dgst -sha1 -verify rsakey.pub.pem -signature input.sha1-rsa.sig input.data
868              
869             =head2 Keys generated by Crypt::PK::RSA
870              
871             Generate keys (Perl code):
872              
873             use Crypt::PK::RSA;
874             use Crypt::Misc 'write_rawfile';
875              
876             my $pkrsa = Crypt::PK::RSA->new;
877             $pkrsa->generate_key(256, 65537);
878             write_rawfile("rsakey.pub.der", $pkrsa->export_key_der('public'));
879             write_rawfile("rsakey.priv.der", $pkrsa->export_key_der('private'));
880             write_rawfile("rsakey.pub.pem", $pkrsa->export_key_pem('public_x509'));
881             write_rawfile("rsakey.priv.pem", $pkrsa->export_key_pem('private'));
882             write_rawfile("rsakey-passwd.priv.pem", $pkrsa->export_key_pem('private', 'secret'));
883              
884             Use keys by OpenSSL:
885              
886             openssl rsa -in rsakey.priv.der -text -inform der
887             openssl rsa -in rsakey.priv.pem -text
888             openssl rsa -in rsakey-passwd.priv.pem -text -inform pem -passin pass:secret
889             openssl rsa -in rsakey.pub.der -pubin -text -inform der
890             openssl rsa -in rsakey.pub.pem -pubin -text
891              
892             =head2 Keys generated by OpenSSL
893              
894             Generate keys:
895              
896             openssl genrsa -out rsakey.priv.pem 1024
897             openssl rsa -in rsakey.priv.pem -out rsakey.priv.der -outform der
898             openssl rsa -in rsakey.priv.pem -out rsakey.pub.pem -pubout
899             openssl rsa -in rsakey.priv.pem -out rsakey.pub.der -outform der -pubout
900             openssl rsa -in rsakey.priv.pem -passout pass:secret -des3 -out rsakey-passwd.priv.pem
901              
902             Load keys (Perl code):
903              
904             use Crypt::PK::RSA;
905              
906             my $pkrsa = Crypt::PK::RSA->new;
907             $pkrsa->import_key("rsakey.pub.der");
908             $pkrsa->import_key("rsakey.priv.der");
909             $pkrsa->import_key("rsakey.pub.pem");
910             $pkrsa->import_key("rsakey.priv.pem");
911             $pkrsa->import_key("rsakey-passwd.priv.pem", "secret");
912              
913             =head1 SEE ALSO
914              
915             =over
916              
917             =item * L
918              
919             =back
920              
921             =cut