Beispiel #1
0
 function generate($key_len = null)
 {
     if (is_null($key_len)) {
         // use an old key length
         $key_len = $this->_key_len;
         if (is_null($key_len)) {
             $this->pushError('missing key_len parameter', CRYPT_RSA_ERROR_MISSING_KEY_LEN);
             return false;
         }
     }
     // minimal key length is 8 bit ;)
     if ($key_len < 8) {
         $key_len = 8;
     }
     // store key length in the _key_len property
     $this->_key_len = $key_len;
     // set [e] to 0x10001 (65537)
     $e = $this->_math_obj->bin2int("");
     // generate [p], [q] and [n]
     $p_len = intval(($key_len + 1) / 2);
     $q_len = $key_len - $p_len;
     $p1 = $q1 = 0;
     do {
         // generate prime number [$p] with length [$p_len] with the following condition:
         // GCD($e, $p - 1) = 1
         do {
             $p = $this->_math_obj->getPrime($p_len, $this->_random_generator);
             $p1 = $this->_math_obj->dec($p);
             $tmp = $this->_math_obj->GCD($e, $p1);
         } while (!$this->_math_obj->isOne($tmp));
         // generate prime number [$q] with length [$q_len] with the following conditions:
         // GCD($e, $q - 1) = 1
         // $q != $p
         do {
             $q = $this->_math_obj->getPrime($q_len, $this->_random_generator);
             $q1 = $this->_math_obj->dec($q);
             $tmp = $this->_math_obj->GCD($e, $q1);
         } while (!$this->_math_obj->isOne($tmp) && !$this->_math_obj->cmpAbs($q, $p));
         // if (p < q), then exchange them
         if ($this->_math_obj->cmpAbs($p, $q) < 0) {
             $tmp = $p;
             $p = $q;
             $q = $tmp;
             $tmp = $p1;
             $p1 = $q1;
             $q1 = $tmp;
         }
         // calculate n = p * q
         $n = $this->_math_obj->mul($p, $q);
     } while ($this->_math_obj->bitLen($n) != $key_len);
     // calculate d = 1/e mod (p - 1) * (q - 1)
     $pq = $this->_math_obj->mul($p1, $q1);
     $d = $this->_math_obj->invmod($e, $pq);
     // calculate dmp1 = d mod (p - 1)
     $dmp1 = $this->_math_obj->mod($d, $p1);
     // calculate dmq1 = d mod (q - 1)
     $dmq1 = $this->_math_obj->mod($d, $q1);
     // calculate iqmp = 1/q mod p
     $iqmp = $this->_math_obj->invmod($q, $p);
     // store RSA keypair attributes
     $this->_attrs = array('version' => "", 'n' => $this->_math_obj->int2bin($n), 'e' => $this->_math_obj->int2bin($e), 'd' => $this->_math_obj->int2bin($d), 'p' => $this->_math_obj->int2bin($p), 'q' => $this->_math_obj->int2bin($q), 'dmp1' => $this->_math_obj->int2bin($dmp1), 'dmq1' => $this->_math_obj->int2bin($dmq1), 'iqmp' => $this->_math_obj->int2bin($iqmp));
     $n = $this->_attrs['n'];
     $e = $this->_attrs['e'];
     $d = $this->_attrs['d'];
     // try to create public key object
     $obj = new Crypt_RSA_Key($n, $e, 'public', $this->_math_obj->getWrapperName(), $this->_error_handler);
     if ($obj->isError()) {
         // error during creating public object
         $this->pushError($obj->getLastError());
         return false;
     }
     $this->_public_key =& $obj;
     // try to create private key object
     $obj = new Crypt_RSA_Key($n, $d, 'private', $this->_math_obj->getWrapperName(), $this->_error_handler);
     if ($obj->isError()) {
         // error during creating private key object
         $this->pushError($obj->getLastError());
         return false;
     }
     $this->_private_key =& $obj;
     return true;
     // key pair successfully generated
 }
Beispiel #2
0
 /**
  * Crypt_RSA_Key factory.
  *
  * @param string $modulus   key modulus
  * @param string $exp       key exponent
  * @param string $key_type  type of the key (public or private)
  *
  * @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.
  *
  * @return object   new Crypt_RSA_Key object on success or PEAR_Error object on failure
  * @access public
  */
 function &factory($modulus, $exp, $key_type, $wrapper_name = 'default')
 {
     $obj = new Crypt_RSA_Key($modulus, $exp, $key_type, $wrapper_name);
     if ($obj->isError()) {
         // error during creating a new object. Retrurn PEAR_Error object
         return $obj->getLastError();
     }
     // object created successfully. Return it
     return $obj;
 }
 /**
  * Generates new Crypt_RSA key pair with length $key_len.
  * If $key_len is missed, use an old key length from $this->_key_len
  *
  * @param int $key_len  bit length of key pair, which will be generated
  * @return bool         true on success or false on error
  * @access public
  */
 function generate($key_len = null)
 {
     if (is_null($key_len)) {
         // use an old key length
         $key_len = $this->_key_len;
         if (is_null($key_len)) {
             $obj = PEAR::raiseError('missing key_len parameter', CRYPT_RSA_ERROR_MISSING_KEY_LEN);
             $this->pushError($obj);
             return false;
         }
     }
     // align $key_len to 8 bits
     if ($key_len & 7) {
         $key_len += 8 - $key_len % 8;
     }
     // store key length in the _key_len property
     $this->_key_len = $key_len;
     // generate two primes p and q
     $p_len = (int) ($key_len / 2) + 1;
     $q_len = $key_len - $p_len;
     $p = $this->_math_obj->getRand($p_len, $this->_random_generator, true);
     $p = $this->_math_obj->nextPrime($p);
     do {
         do {
             $q = $this->_math_obj->getRand($q_len, $this->_random_generator, true);
             $tmp_len = $this->_math_obj->bitLen($this->_math_obj->mul($p, $q));
             if ($tmp_len < $key_len) {
                 $q_len++;
             } elseif ($tmp_len > $key_len) {
                 $q_len--;
             }
         } while ($tmp_len != $key_len);
         $q = $this->_math_obj->nextPrime($q);
         $tmp = $this->_math_obj->mul($p, $q);
     } while ($this->_math_obj->bitLen($tmp) != $key_len);
     // $n - is shared modulus
     $n = $this->_math_obj->mul($p, $q);
     // generate public ($e) and private ($d) keys
     $pq = $this->_math_obj->mul($this->_math_obj->dec($p), $this->_math_obj->dec($q));
     do {
         $e = $this->_math_obj->getRand($q_len, $this->_random_generator);
         if ($this->_math_obj->isZero($e) || $this->_math_obj->isZero($this->_math_obj->dec($e))) {
             // exponent cannot be equal to 0 or 1
             continue;
         }
         if ($this->_math_obj->isZero($this->_math_obj->dec($this->_math_obj->gcd($e, $pq)))) {
             // exponent is found
             break;
         }
     } while (true);
     $d = $this->_math_obj->invmod($e, $pq);
     $modulus = $this->_math_obj->int2bin($n);
     $public_exp = $this->_math_obj->int2bin($e);
     $private_exp = $this->_math_obj->int2bin($d);
     // try to create public key object
     $obj = new Crypt_RSA_Key($modulus, $public_exp, 'public', $this->_math_obj->getWrapperName(), $this->_error_handler);
     if ($obj->isError()) {
         // error during creating public object
         $this->pushError($obj->getLastError());
         return false;
     }
     $this->_public_key = $obj;
     // try to create private key object
     $obj = new Crypt_RSA_Key($modulus, $private_exp, 'private', $this->_math_obj->getWrapperName(), $this->_error_handler);
     if ($obj->isError()) {
         // error during creating private key object
         $this->pushError($obj->getLastError());
         return false;
     }
     $this->_private_key = $obj;
     return true;
     // key pair successfully generated
 }