Beispiel #1
0
 /**
  * Crypt_RSA_KeyPair constructor.
  *
  * @param int $key_len bit length of key pair, which will be generated in constructor
  * @param string $wrapper_name
  *        Name of math wrapper, which will be used to
  *        perform different operations with big integers.
  *        See contents of Crypt/RSA/Math folder for examples of wrappers.
  *        Read docs/Crypt_RSA/docs/math_wrappers.txt for details.
  * @param string $error_handler   name of error handler function
  * @param callback $random_generator function which will be used as random generator
  *
  * @access public
  */
 function Crypt_RSA_KeyPair($key_len, $wrapper_name = 'default', $error_handler = '', $random_generator = null)
 {
     // set error handler
     $this->setErrorHandler($error_handler);
     // try to load math wrapper
     $obj =& Crypt_RSA_MathLoader::loadWrapper($wrapper_name);
     if ($this->isError($obj)) {
         // error during loading of math wrapper
         $this->pushError($obj);
         return;
     }
     $this->_math_obj =& $obj;
     // set random generator
     if (!$this->setRandomGenerator($random_generator)) {
         // error in setRandomGenerator() function
         return;
     }
     if (is_array($key_len)) {
         // ugly BC hack - it is possible to pass RSA private key attributes [version, n, e, d, p, q, dmp1, dmq1, iqmp]
         // as associative array instead of key length to Crypt_RSA_KeyPair constructor
         $rsa_attrs = $key_len;
         // convert attributes to big integers
         $attr_names = $this->_get_attr_names();
         foreach ($attr_names as $attr) {
             if (!isset($rsa_attrs[$attr])) {
                 $this->pushError("missing required RSA attribute [{$attr}]");
                 return;
             }
             ${$attr} = $this->_math_obj->bin2int($rsa_attrs[$attr]);
         }
         // check primality of p and q
         if (!$this->_math_obj->isPrime($p)) {
             $this->pushError("[p] must be prime");
             return;
         }
         if (!$this->_math_obj->isPrime($q)) {
             $this->pushError("[q] must be prime");
             return;
         }
         // check n = p * q
         $n1 = $this->_math_obj->mul($p, $q);
         if ($this->_math_obj->cmpAbs($n, $n1)) {
             $this->pushError("n != p * q");
             return;
         }
         // check e * d = 1 mod (p-1) * (q-1)
         $p1 = $this->_math_obj->dec($p);
         $q1 = $this->_math_obj->dec($q);
         $p1q1 = $this->_math_obj->mul($p1, $q1);
         $ed = $this->_math_obj->mul($e, $d);
         $one = $this->_math_obj->mod($ed, $p1q1);
         if (!$this->_math_obj->isOne($one)) {
             $this->pushError("e * d != 1 mod (p-1)*(q-1)");
             return;
         }
         // check dmp1 = d mod (p-1)
         $dmp = $this->_math_obj->mod($d, $p1);
         if ($this->_math_obj->cmpAbs($dmp, $dmp1)) {
             $this->pushError("dmp1 != d mod (p-1)");
             return;
         }
         // check dmq1 = d mod (q-1)
         $dmq = $this->_math_obj->mod($d, $q1);
         if ($this->_math_obj->cmpAbs($dmq, $dmq1)) {
             $this->pushError("dmq1 != d mod (q-1)");
             return;
         }
         // check iqmp = 1/q mod p
         $q1 = $this->_math_obj->invmod($iqmp, $p);
         if ($this->_math_obj->cmpAbs($q, $q1)) {
             $this->pushError("iqmp != 1/q mod p");
             return;
         }
         // try to create public key object
         $public_key = new Crypt_RSA_Key($rsa_attrs['n'], $rsa_attrs['e'], 'public', $wrapper_name, $error_handler);
         if ($public_key->isError()) {
             // error during creating public object
             $this->pushError($public_key->getLastError());
             return;
         }
         // try to create private key object
         $private_key = new Crypt_RSA_Key($rsa_attrs['n'], $rsa_attrs['d'], 'private', $wrapper_name, $error_handler);
         if ($private_key->isError()) {
             // error during creating private key object
             $this->pushError($private_key->getLastError());
             return;
         }
         $this->_public_key = $public_key;
         $this->_private_key = $private_key;
         $this->_key_len = $public_key->getKeyLength();
         $this->_attrs = $rsa_attrs;
     } else {
         // generate key pair
         if (!$this->generate($key_len)) {
             // error during generating key pair
             return;
         }
     }
 }