home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / OAEP.pm < prev    next >
Encoding:
Perl POD Document  |  2003-01-08  |  8.4 KB  |  287 lines

  1. #!/usr/bin/perl -sw
  2. ##
  3. ## Crypt::RSA::ES::OAEP 
  4. ##
  5. ## Copyright (c) 2001, Vipul Ved Prakash.  All rights reserved.
  6. ## This code is free software; you can redistribute it and/or modify
  7. ## it under the same terms as Perl itself.
  8. ##
  9. ## $Id: OAEP.pm,v 1.24 2001/06/22 23:27:37 vipul Exp $
  10.  
  11. package Crypt::RSA::ES::OAEP; 
  12. use lib qw(lib);
  13. use strict;
  14. use vars qw(@ISA $VERSION);
  15. use Crypt::Random          qw(makerandom_octet);
  16. use Crypt::RSA::Errorhandler; 
  17. use Crypt::RSA::DataFormat qw(bitsize os2ip i2osp octet_xor mgf1 octet_len);
  18. use Crypt::RSA::Primitives;
  19. use Crypt::RSA::Debug      qw(debug);
  20. use Digest::SHA1           qw(sha1);
  21. use Math::Pari             qw(floor);
  22. use Sort::Versions         qw(versioncmp);
  23. use Carp;
  24. @ISA = qw(Crypt::RSA::Errorhandler);
  25. ($VERSION)  = '$Revision: 1.24 $' =~ /\s(\d+\.\d+)\s/; 
  26.  
  27. sub new { 
  28.     my ($class, %params) = @_;
  29.     my $self = bless { primitives => new Crypt::RSA::Primitives, 
  30.                        P          => "",
  31.                        hlen       => 20,
  32.                        VERSION    => $VERSION,
  33.                       }, $class;
  34.     if ($params{Version}) { 
  35.         if (versioncmp($params{Version}, '1.15') == -1) { 
  36.             $$self{P} = "Crypt::RSA"; 
  37.             $$self{VERSION} = $params{Version};
  38.         } elsif (versioncmp($params{Version}, $$self{VERSION}) == 1) { 
  39.             croak "Required version ($params{Version}) greater than installed version ($$self{VERSION}) of $class.\n";
  40.         }
  41.     }
  42.     return $self;
  43. }
  44.  
  45.  
  46. sub encrypt { 
  47.     my ($self, %params) = @_; 
  48.     my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
  49.     return $self->error ($key->errstr, \$M, $key, \%params) unless $key->check;
  50.     my $k = octet_len ($key->n);  debug ("octet_len of modulus: $k");
  51.     my $em = $self->encode ($M, $self->{P}, $k-1) || 
  52.         return $self->error ($self->errstr, \$M, $key, \%params);
  53.     my $m = os2ip ($em);
  54.     my $c = $self->{primitives}->core_encrypt ( Plaintext => $m, Key => $key );
  55.     my $ec = i2osp ($c, $k);  debug ("ec: $ec");
  56.     return $ec;
  57. }    
  58.  
  59.  
  60. sub decrypt { 
  61.     my ($self, %params) = @_;
  62.     my $key = $params{Key}; my $C = $params{Cyphertext} || $params{Ciphertext}; 
  63.     return $self->error ($key->errstr, $key, \%params) unless $key->check;
  64.     my $k = octet_len ($key->n);  
  65.     my $c = os2ip ($C);
  66.     if (bitsize($c) > bitsize($key->n)) { 
  67.         return $self->error ("Decryption error.", $key, \%params) 
  68.     }
  69.     my $m = $self->{primitives}->core_decrypt (Cyphertext => $c, Key => $key) || 
  70.         return $self->error ("Decryption error.", $key, \%params);
  71.     my $em = i2osp ($m, $k-1) || 
  72.         return $self->error ("Decryption error.", $key, \%params);
  73.     my $M; $self->errstrrst;  # reset the errstr
  74.     unless ($M = $self->decode ($em, $$self{P})) { 
  75.         return $self->error ("Decryption error.", $key, \%params) if $self->errstr();
  76.         return $M;
  77.     } 
  78.     return $M;
  79.  
  80.  
  81. sub encode { 
  82.     my ($self, $M, $P, $emlen) = @_; 
  83.     my $hlen = $$self{hlen};
  84.     my $mlen = length($M);
  85.     return $self->error ("Message too long.", \$P, \$M) if $mlen > $emlen-(2*$hlen)-1;
  86.     my ($PS, $pslen) = ("", 0);
  87.     if ($pslen = $emlen-(2*$hlen+1+$mlen)) { 
  88.         $PS = chr(0)x$pslen;
  89.     }
  90.     my $phash = $self->hash ($P);
  91.     my $db = $phash . $PS . chr(1) . $M; 
  92.     my $seed = makerandom_octet (Length => $hlen);
  93.     my $dbmask = $self->mgf ($seed, $emlen-$hlen);
  94.     my $maskeddb = octet_xor ($db, $dbmask);
  95.     my $seedmask = $self->mgf ($maskeddb, $hlen);
  96.     my $maskedseed = octet_xor ($seed, $seedmask);
  97.     my $em = $maskedseed . $maskeddb;
  98.  
  99.     debug ("emlen == $emlen");
  100.     debug ("M == $M [" . length($M) . "]"); 
  101.     debug ("PS == $PS [$pslen]"); 
  102.     debug ("phash == $phash [" . length($phash) . "]"); 
  103.     debug ("seed == $seed [" . length($seed) . "]"); 
  104.     debug ("seedmask == $seedmask [" . length($seedmask) . "]"); 
  105.     debug ("db == $db [" . length($db) . "]"); 
  106.     debug ("dbmask == $dbmask [" . length($dbmask) . "]"); 
  107.     debug ("maskeddb == $maskeddb [" . length($maskeddb) . "]"); 
  108.     debug ("em == $em [" . length($em) . "]"); 
  109.  
  110.     return $em;
  111. }
  112.  
  113.  
  114. sub decode { 
  115.     my ($self, $em, $P) = @_; 
  116.     my $hlen = $$self{hlen};
  117.  
  118.     debug ("P == $P");
  119.     return $self->error ("Decoding error.", \$P) if length($em) < 2*$hlen+1;
  120.     my $maskedseed = substr $em, 0, $hlen; 
  121.     my $maskeddb = substr $em, $hlen; 
  122.     my $seedmask = $self->mgf ($maskeddb, $hlen);
  123.     my $seed = octet_xor ($maskedseed, $seedmask);
  124.     my $dbmask = $self->mgf ($seed, length($em) - $hlen);
  125.     my $db = octet_xor ($maskeddb, $dbmask); 
  126.     my $phash = $self->hash ($P); 
  127.  
  128.     debug ("em == $em [" . length($em) . "]"); 
  129.     debug ("phash == $phash [" . length($phash) . "]"); 
  130.     debug ("seed == $seed [" . length($seed) . "]"); 
  131.     debug ("seedmask == $seedmask [" . length($seedmask) . "]"); 
  132.     debug ("maskedseed == $maskedseed [" . length($maskedseed) . "]"); 
  133.     debug ("db == $db [" . length($db) . "]"); 
  134.     debug ("maskeddb == $maskeddb [" . length($maskeddb) . "]"); 
  135.     debug ("dbmask == $dbmask [" . length($dbmask) . "]"); 
  136.  
  137.     my ($phashorig) = substr $db, 0, $hlen;
  138.     debug ("phashorig == $phashorig [" . length($phashorig) . "]"); 
  139.     return $self->error ("Decoding error.", \$P) unless $phashorig eq $phash; 
  140.     $db = substr $db, $hlen;
  141.     my ($chr0, $chr1) = (chr(0), chr(1));
  142.     my ($ps, $m);
  143.     debug ("db == $db [" . length($db) . "]"); 
  144.     unless ( ($ps, undef, $m) = $db =~ /^($chr0*)($chr1)(.*)$/s ) { 
  145.         return $self->error ("Decoding error.", \$P);
  146.     } 
  147.  
  148.     return $m;
  149. }
  150.  
  151.  
  152. sub hash { 
  153.     my ($self, $data) = @_;
  154.     return sha1 ($data);
  155. }
  156.  
  157.  
  158. sub mgf {
  159.     my ($self, @data) = @_;
  160.     return mgf1 (@data);
  161. }
  162.  
  163.  
  164. sub encryptblock { 
  165.     my ($self, %params) = @_;
  166.     return octet_len ($params{Key}->n) - 42;
  167.  
  168.  
  169. sub decryptblock { 
  170.     my ($self, %params) = @_;
  171.     return octet_len ($params{Key}->n);
  172. }
  173.  
  174.  
  175. # should be able to call this as a class method.
  176. sub version {
  177.     my $self = shift;
  178.     return $self->{VERSION};
  179. }
  180.  
  181.  
  182. 1;
  183.  
  184. =head1 NAME
  185.  
  186. Crypt::RSA::ES::OAEP - Plaintext-aware encryption with RSA. 
  187.  
  188. =head1 SYNOPSIS
  189.  
  190.     my $oaep = new Crypt::RSA::ES::OAEP; 
  191.  
  192.     my $ct = $oaep->encrypt( Key => $key, Message => $message ) || 
  193.                 die $oaep->errstr; 
  194.  
  195.     my $pt = $oaep->decrypt( Key => $key, Cyphertext => $ct )   || 
  196.                 die $oaep->errstr; 
  197.  
  198. =head1 DESCRIPTION
  199.  
  200. This module implements Optimal Asymmetric Encryption, a plaintext-aware
  201. encryption scheme based on RSA. The notion of plaintext-aware implies it's
  202. computationally infeasible to obtain full or partial information about a
  203. message from a cyphertext, and computationally infeasible to generate a
  204. valid cyphertext without knowing the corresponding message.
  205. Plaintext-aware schemes, such as OAEP, are semantically secure,
  206. non-malleable and secure against chosen-ciphertext attack. For more
  207. information on OAEP and plaintext-aware encryption, see [3], [9] & [13].
  208.  
  209. =head1 METHODS
  210.  
  211. =head2 B<new()>
  212.  
  213. Constructor. 
  214.  
  215. =head2 B<version()>
  216.  
  217. Returns the version number of the module.
  218.  
  219. =head2 B<encrypt()>
  220.  
  221. Encrypts a string with a public key and returns the encrypted string
  222. on success. encrypt() takes a hash argument with the following
  223. mandatory keys:
  224.  
  225. =over 4
  226.  
  227. =item B<Message>
  228.  
  229. A string to be encrypted. The length of this string should not exceed k-42
  230. octets, where k is the octet length of the RSA modulus. If Message is
  231. longer than k-42, the method will fail and set $self->errstr to "Message
  232. too long."
  233.  
  234. =item B<Key>
  235.  
  236. Public key of the recipient, a Crypt::RSA::Key::Public object.
  237.  
  238. =back
  239.  
  240. =head2 B<decrypt()>
  241.  
  242. Decrypts cyphertext with a private key and returns plaintext on
  243. success. $self->errstr is set to "Decryption Error." or appropriate
  244. error on failure. decrypt() takes a hash argument with the following
  245. mandatory keys:
  246.  
  247. =over 4
  248.  
  249. =item B<Cyphertext>
  250.  
  251. A string encrypted with encrypt(). The length of the cyphertext must be k
  252. octets, where k is the length of the RSA modulus.
  253.  
  254. =item B<Key>
  255.  
  256. Private key of the receiver, a Crypt::RSA::Key::Private object.
  257.  
  258. =item B<Version>
  259.  
  260. Version of the module that was used for creating the Cyphertext. This is
  261. an optional argument. When present, decrypt() will ensure before
  262. proceeding that the installed version of the module can successfully
  263. decrypt the Cyphertext.
  264.  
  265. =head1 ERROR HANDLING
  266.  
  267. See ERROR HANDLING in Crypt::RSA(3) manpage.
  268.  
  269. =head1 BIBLIOGRAPHY 
  270.  
  271. See BIBLIOGRAPHY in Crypt::RSA(3) manpage.
  272.  
  273. =head1 AUTHOR
  274.  
  275. Vipul Ved Prakash, E<lt>mail@vipul.netE<gt>
  276.  
  277. =head1 SEE ALSO 
  278.  
  279. Crypt::RSA(3), Crypt::RSA::Primitives(3), Crypt::RSA::Keys(3),
  280. Crypt::RSA::SSA::PSS(3)
  281.  
  282. =cut
  283.  
  284.  
  285.