Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
form di login crittografata senza Https - jcryption.php

jcryption.php

Caricato da:
Scarica il programma completo

  1. <?php
  2.         /**
  3.         * jCryption
  4.         *
  5.         * PHP versions 4 and 5
  6.         *
  7.         * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.         * that is available through the world-wide-web at the following URI:
  9.         * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.         * the PHP License and are unable to obtain it through the web, please
  11.         * send a note to license@php.net so we can mail you a copy immediately.
  12.         *
  13.         * Many of the functions in this class are from the PEAR Crypt_RSA package ...
  14.         * So most of the credits goes to the original creator of this package Alexander Valyalkin
  15.         * you can get the package under http://pear.php.net/package/Crypt_RSA
  16.         *
  17.         * I just changed, added, removed and improved some functions to fit the needs of jCryption
  18.         *
  19.         * @author     Daniel Griesser <daniel.griesser@jcryption.org>
  20.         * @copyright  2010 Daniel Griesser
  21.         * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  22.         * @version    1.1
  23.         * @link       http://jcryption.org/
  24.         */
  25.         class jCryption {
  26.  
  27.                 var $_key_len;
  28.                 var $_e;
  29.  
  30.                 /**
  31.                 * Constructor
  32.                 *
  33.                 * @access public
  34.                 */
  35.                 function jCryption($e = "\x01\x00\x01") {
  36.                         $this->_e = $e;
  37.                 }
  38.  
  39.                 /**
  40.                 * Generates the Keypair with the given keyLength the encryption key e ist set staticlly
  41.                 * set to 65537 for faster encryption.
  42.                 *
  43.                 * @param int $keyLength
  44.                 * @return array
  45.                 * @access public
  46.                 */
  47.                 function generateKeypair($keyLength) {
  48.                         $this->_key_len = intval($keyLength);
  49.                         if ($this->_key_len < 8) {
  50.                                 $this->_key_len = 8;
  51.                         }
  52.  
  53.                         // set [e] to 0x10001 (65537)
  54.                         $e = $this->bin2int($this->_e);
  55.  
  56.                         // generate [p], [q] and [n]
  57.                         $p_len = intval(($this->_key_len + 1) / 2);
  58.                         $q_len = $this->_key_len - $p_len;
  59.                         $p1 = $q1 = 0;
  60.                         do {
  61.                                 // generate prime number [$p] with length [$p_len] with the following condition:
  62.                                 // GCD($e, $p - 1) = 1
  63.  
  64.                                 do {
  65.                                         $p = $this->getPrime($p_len);
  66.                                         $p1 = $this->dec($p);
  67.                                         $tmp = $this->GCD($e, $p1);
  68.                                 } while (!$this->isOne($tmp));
  69.                                 // generate prime number [$q] with length [$q_len] with the following conditions:
  70.                                 // GCD($e, $q - 1) = 1
  71.                                 // $q != $p
  72.  
  73.                                 do {
  74.                                         $q = $this->getPrime($q_len);
  75.                                         //$q = 102238965184417281201422828818276460200050705922822343263269460146519295919831;
  76.                                         $q1 = $this->dec($q);
  77.                                         $tmp = $this->GCD($e, $q1);
  78.                                 } while (!$this->isOne($tmp) && !$this->cmpAbs($q, $p));
  79.  
  80.                                 // if (p < q), then exchange them
  81.                                 if ($this->cmpAbs($p, $q) < 0) {
  82.                                         $tmp = $p;
  83.                                         $p = $q;
  84.                                         $q = $tmp;
  85.                                         $tmp = $p1;
  86.                                         $p1 = $q1;
  87.                                         $q1 = $tmp;
  88.                                 }
  89.                                 // calculate n = p * q
  90.                                 $n = $this->mul($p, $q);
  91.  
  92.                         } while ($this->bitLen($n) != $this->_key_len);
  93.  
  94.                         // calculate d = 1/e mod (p - 1) * (q - 1)
  95.                         $pq = $this->mul($p1, $q1);
  96.                         $d = $this->invmod($e, $pq);
  97.  
  98.                         // store RSA keypair attributes
  99.                         $keypair = array('n'=>$n, 'e'=>$e, 'd'=>$d, 'p'=>$p, 'q'=>$q);
  100.  
  101.                         return $keypair;
  102.                 }
  103.  
  104.                 function useKeys($keys,$keyLength) {
  105.                         $this->_key_len = intval($keyLength);
  106.                         if ($this->_key_len < 8) {
  107.                                 $this->_key_len = 8;
  108.                         }
  109.  
  110.                         // set [e] to 0x10001 (65537)
  111.                         $e = $this->bin2int($this->_e);
  112.  
  113.                         // generate [p], [q] and [n]
  114.                         $p_len = intval(($this->_key_len + 1) / 2);
  115.                         $q_len = $this->_key_len - $p_len;
  116.                         $p1 = $q1 = 0;
  117.                         do {
  118.                                 do {
  119.                                         $q = $keys[rand(0,count($keys))];
  120.                                         $p = $keys[rand(0,count($keys))];
  121.                                         $p1 = $this->dec($p);
  122.                                         $q1 = $this->dec($q);
  123.                                 } while (!$this->cmpAbs($q, $p));
  124.  
  125.  
  126.                                 // if (p < q), then exchange them
  127.                                 if ($this->cmpAbs($p, $q) < 0) {
  128.                                         $tmp = $p;
  129.                                         $p = $q;
  130.                                         $q = $tmp;
  131.                                         $tmp = $p1;
  132.                                         $p1 = $q1;
  133.                                         $q1 = $tmp;
  134.                                 }
  135.                                 // calculate n = p * q
  136.                                 $n = $this->mul($p, $q);
  137.  
  138.                         } while ($this->bitLen($n) != $this->_key_len);
  139.  
  140.                         // calculate d = 1/e mod (p - 1) * (q - 1)
  141.                         $pq = $this->mul($p1, $q1);
  142.                         $d = $this->invmod($e, $pq);
  143.  
  144.                         // store RSA keypair attributes
  145.                         $keypair = array('n'=>$n, 'e'=>$e, 'd'=>$d, 'p'=>$p, 'q'=>$q);
  146.  
  147.                         return $keypair;
  148.                 }
  149.  
  150.                 /**
  151.                 * Finds greatest common divider (GCD) of $num1 and $num2
  152.                 *
  153.                 * @param string $num1
  154.                 * @param string $num2
  155.                 * @return string
  156.                 * @access public
  157.                 */
  158.                 function GCD($num1, $num2) {
  159.                         do {
  160.                                 $tmp = bcmod($num1, $num2);
  161.                                 $num1 = $num2;
  162.                                 $num2 = $tmp;
  163.                         } while (bccomp($num2, '0'));
  164.                         return $num1;
  165.                 }
  166.  
  167.                 /**
  168.                 * Performs Miller-Rabin primality test for number $num
  169.                 * with base $base. Returns true, if $num is strong pseudoprime
  170.                 * by base $base. Else returns false.
  171.                 *
  172.                 * @param string $num
  173.                 * @param string $base
  174.                 * @return bool
  175.                 * @access private
  176.                 */
  177.                 function _millerTest($num, $base) {
  178.                         if (!bccomp($num, '1')) {
  179.                                 // 1 is not prime ;)
  180.                                 return false;
  181.                         }
  182.                         $tmp = bcsub($num, '1');
  183.  
  184.                         $zero_bits = 0;
  185.                         while (!bccomp(bcmod($tmp, '2'), '0')) {
  186.                                 $zero_bits++;
  187.                                 $tmp = bcdiv($tmp, '2');
  188.                         }
  189.  
  190.                         $tmp = $this->powmod($base, $tmp, $num);
  191.                         if (!bccomp($tmp, '1')) {
  192.                                 // $num is probably prime
  193.                                 return true;
  194.                         }
  195.  
  196.                         while ($zero_bits--) {
  197.                                 if (!bccomp(bcadd($tmp, '1'), $num)) {
  198.                                         // $num is probably prime
  199.                                         return true;
  200.                                 }
  201.                                 $tmp = $this->powmod($tmp, '2', $num);
  202.                         }
  203.                         // $num is composite
  204.                         return false;
  205.                 }
  206.  
  207.                 /**
  208.                 * Transforms binary representation of large integer into its native form.
  209.                 *
  210.                 * Example of transformation:
  211.                 *    $str = "\x12\x34\x56\x78\x90";
  212.                 *    $num = 0x9078563412;
  213.                 *
  214.                 * @param string $str
  215.                 * @return string
  216.                 * @access public
  217.                 */
  218.                 function bin2int($str) {
  219.                         $result = '0';
  220.                         $n = strlen($str);
  221.                         do {
  222.                                 $result = bcadd(bcmul($result, '256'), ord($str {--$n} ));
  223.                         } while ($n > 0);
  224.                         return $result;
  225.                 }
  226.  
  227.                 /**
  228.                 * Transforms large integer into binary representation.
  229.                 *
  230.                 * Example of transformation:
  231.                 *    $num = 0x9078563412;
  232.                 *    $str = "\x12\x34\x56\x78\x90";
  233.                 *
  234.                 * @param string $num
  235.                 * @return string
  236.                 * @access public
  237.                 */
  238.                 function int2bin($num) {
  239.                         $result = '';
  240.                         do {
  241.                                 $result .= chr(bcmod($num, '256'));
  242.                                 $num = bcdiv($num, '256');
  243.                         } while (bccomp($num, '0'));
  244.                         return $result;
  245.                 }
  246.  
  247.                 /**
  248.                 * Calculates pow($num, $pow) (mod $mod)
  249.                 *
  250.                 * @param string $num
  251.                 * @param string $pow
  252.                 * @param string $mod
  253.                 * @return string
  254.                 * @access public
  255.                 */
  256.                 function powmod($num, $pow, $mod) {
  257.                         if (function_exists('bcpowmod')) {
  258.                                 // bcpowmod is only available under PHP5
  259.                                 return bcpowmod($num, $pow, $mod);
  260.                         }
  261.  
  262.                         // emulate bcpowmod
  263.                         $result = '1';
  264.                         do {
  265.                                 if (!bccomp(bcmod($pow, '2'), '1')) {
  266.                                         $result = bcmod(bcmul($result, $num), $mod);
  267.                                 }
  268.                                 $num = bcmod(bcpow($num, '2'), $mod);
  269.                                 $pow = bcdiv($pow, '2');
  270.                         } while (bccomp($pow, '0'));
  271.                         return $result;
  272.                 }
  273.  
  274.                 /**
  275.                 * Calculates $num1 * $num2
  276.                 *
  277.                 * @param string $num1
  278.                 * @param string $num2
  279.                 * @return string
  280.                 * @access public
  281.                 */
  282.                 function mul($num1, $num2) {
  283.                         return bcmul($num1, $num2);
  284.                 }
  285.  
  286.                 /**
  287.                 * Calculates $num1 % $num2
  288.                 *
  289.                 * @param string $num1
  290.                 * @param string $num2
  291.                 * @return string
  292.                 * @access public
  293.                 */
  294.                 function mod($num1, $num2) {
  295.                         return bcmod($num1, $num2);
  296.                 }
  297.  
  298.                 /**
  299.                 * Compares abs($num1) to abs($num2).
  300.                 * Returns:
  301.                 *   -1, if abs($num1) < abs($num2)
  302.                 *   0, if abs($num1) == abs($num2)
  303.                 *   1, if abs($num1) > abs($num2)
  304.                 *
  305.                 * @param string $num1
  306.                 * @param string $num2
  307.                 * @return int
  308.                 * @access public
  309.                 */
  310.                 function cmpAbs($num1, $num2) {
  311.                         return bccomp($num1, $num2);
  312.                 }
  313.  
  314.                 /**
  315.                 * Tests $num on primality. Returns true, if $num is strong pseudoprime.
  316.                 * Else returns false.
  317.                 *
  318.                 * @param string $num
  319.                 * @return bool
  320.                 * @access private
  321.                 */
  322.                 function isPrime($num) {
  323.                         static $primes = null;
  324.                         static $primes_cnt = 0;
  325.                         if (is_null($primes)) {
  326.                                 // generate all primes up to 10000
  327.                                 $primes = array();
  328.                                 for ($i = 0; $i < 10000; $i++) {
  329.                                         $primes[] = $i;
  330.                                 }
  331.                                 $primes[0] = $primes[1] = 0;
  332.                                 for ($i = 2; $i < 100; $i++) {
  333.                                         while (!$primes[$i]) {
  334.                                                 $i++;
  335.                                         }
  336.                                         $j = $i;
  337.                                         for ($j += $i; $j < 10000; $j += $i) {
  338.                                                 $primes[$j] = 0;
  339.                                         }
  340.                                 }
  341.                                 $j = 0;
  342.                                 for ($i = 0; $i < 10000; $i++) {
  343.                                         if ($primes[$i]) {
  344.                                                 $primes[$j++] = $primes[$i];
  345.                                         }
  346.                                 }
  347.                                 $primes_cnt = $j;
  348.                         }
  349.  
  350.                         // try to divide number by small primes
  351.                         for ($i = 0; $i < $primes_cnt; $i++) {
  352.                                 if (bccomp($num, $primes[$i]) <= 0) {
  353.                                         // number is prime
  354.                                         return true;
  355.                                 }
  356.                                 if (!bccomp(bcmod($num, $primes[$i]), '0')) {
  357.                                         // number divides by $primes[$i]
  358.                                         return false;
  359.                                 }
  360.                         }
  361.  
  362.                         /*
  363.                         try Miller-Rabin's probable-primality test for first
  364.                         7 primes as bases
  365.                         */
  366.                         for ($i = 0; $i < 7; $i++) {
  367.                                 if (!$this->_millerTest($num, $primes[$i])) {
  368.                                         // $num is composite
  369.                                         return false;
  370.                                 }
  371.                         }
  372.                         // $num is strong pseudoprime
  373.                         return true;
  374.                 }
  375.  
  376.                 /**
  377.                 * Produces a better random number
  378.                 * for seeding mt_rand()
  379.                 *
  380.                 * @access private
  381.                 */
  382.                 function _makeSeed() {
  383.                         return hexdec(sha1(sha1(microtime()*mt_rand()).md5(microtime()*mt_rand())));
  384.                 }
  385.  
  386.                 /**
  387.                 * Generates prime number with length $bits_cnt
  388.                 *
  389.                 * @param int $bits_cnt
  390.                 * @access public
  391.                 */
  392.                 function getPrime($bits_cnt) {
  393.                         $bytes_n = intval($bits_cnt / 8);
  394.                         $bits_n = $bits_cnt % 8;
  395.                         do {
  396.                                 $str = '';
  397.                                 mt_srand($this->_makeSeed());
  398.                                 for ($i = 0; $i < $bytes_n; $i++) {
  399.                                         $str .= chr(sha1(mt_rand() * microtime()) & 0xff);
  400.                                 }
  401.                                 $n = mt_rand() * microtime() & 0xff;
  402.  
  403.                                 $n |= 0x80;
  404.                                 $n >>= 8 - $bits_n;
  405.                                 $str .= chr($n);
  406.                                 $num = $this->bin2int($str);
  407.  
  408.                                 // search for the next closest prime number after [$num]
  409.                                 if (!bccomp(bcmod($num, '2'), '0')) {
  410.                                         $num = bcadd($num, '1');
  411.                                 }
  412.                                 while (!$this->isPrime($num)) {
  413.                                         $num = bcadd($num, '2');
  414.                                 }
  415.  
  416.                         } while ($this->bitLen($num) != $bits_cnt);
  417.                         return $num;
  418.                 }
  419.  
  420.                 /**
  421.                 * Calculates $num - 1
  422.                 *
  423.                 * @param string $num
  424.                 * @return string
  425.                 * @access public
  426.                 */
  427.                 function dec($num) {
  428.                         return bcsub($num, '1');
  429.                 }
  430.  
  431.                 /**
  432.                 * Returns true, if $num is equal to one. Else returns false
  433.                 *
  434.                 * @param string $num
  435.                 * @return bool
  436.                 * @access public
  437.                 */
  438.                 function isOne($num) {
  439.                         return !bccomp($num, '1');
  440.                 }
  441.  
  442.                 /**
  443.                 * Finds inverse number $inv for $num by modulus $mod, such as:
  444.                 *     $inv * $num = 1 (mod $mod)
  445.                 *
  446.                 * @param string $num
  447.                 * @param string $mod
  448.                 * @return string
  449.                 * @access public
  450.                 */
  451.                 function invmod($num, $mod) {
  452.                         $x = '1';
  453.                         $y = '0';
  454.                         $num1 = $mod;
  455.                         do {
  456.                                 $tmp = bcmod($num, $num1);
  457.                                 $q = bcdiv($num, $num1);
  458.                                 $num = $num1;
  459.                                 $num1 = $tmp;
  460.  
  461.                                 $tmp = bcsub($x, bcmul($y, $q));
  462.                                 $x = $y;
  463.                                 $y = $tmp;
  464.                         } while (bccomp($num1, '0'));
  465.                         if (bccomp($x, '0') < 0) {
  466.                                 $x = bcadd($x, $mod);
  467.                         }
  468.                         return $x;
  469.                 }
  470.  
  471.                 /**
  472.                 * Returns bit length of number $num
  473.                 *
  474.                 * @param string $num
  475.                 * @return int
  476.                 * @access public
  477.                 */
  478.                 function bitLen($num) {
  479.                         $tmp = $this->int2bin($num);
  480.                         $bit_len = strlen($tmp) * 8;
  481.                         $tmp = ord($tmp {strlen($tmp) - 1} );
  482.                         if (!$tmp) {
  483.                                 $bit_len -= 8;
  484.                         } else {
  485.                                 while (!($tmp & 0x80)) {
  486.                                         $bit_len--;
  487.                                         $tmp <<= 1;
  488.                                 }
  489.                         }
  490.                         return $bit_len;
  491.                 }
  492.  
  493.                 /**
  494.                 * Calculates bitwise or of $num1 and $num2,
  495.                 * starting from bit $start_pos for number $num1
  496.                 *
  497.                 * @param string $num1
  498.                 * @param string $num2
  499.                 * @param int $start_pos
  500.                 * @return string
  501.                 * @access public
  502.                 */
  503.                 function bitOr($num1, $num2, $start_pos) {
  504.                         $start_byte = intval($start_pos / 8);
  505.                         $start_bit = $start_pos % 8;
  506.                         $tmp1 = $this->int2bin($num1);
  507.  
  508.                         $num2 = bcmul($num2, 1 << $start_bit);
  509.                         $tmp2 = $this->int2bin($num2);
  510.                         if ($start_byte < strlen($tmp1)) {
  511.                                 $tmp2 |= substr($tmp1, $start_byte);
  512.                                 $tmp1 = substr($tmp1, 0, $start_byte).$tmp2;
  513.                         } else {
  514.                                 $tmp1 = str_pad($tmp1, $start_byte, "\0").$tmp2;
  515.                         }
  516.                         return $this->bin2int($tmp1);
  517.                 }
  518.  
  519.                 /**
  520.                 * Returns part of number $num, starting at bit
  521.                 * position $start with length $length
  522.                 *
  523.                 * @param string $num
  524.                 * @param int start
  525.                 * @param int length
  526.                 * @return string
  527.                 * @access public
  528.                 */
  529.                 function subint($num, $start, $length) {
  530.                         $start_byte = intval($start / 8);
  531.                         $start_bit = $start % 8;
  532.                         $byte_length = intval($length / 8);
  533.                         $bit_length = $length % 8;
  534.                         if ($bit_length) {
  535.                                 $byte_length++;
  536.                         }
  537.                         $num = bcdiv($num, 1 << $start_bit);
  538.                         $tmp = substr($this->int2bin($num), $start_byte, $byte_length);
  539.                         $tmp = str_pad($tmp, $byte_length, "\0");
  540.                         $tmp = substr_replace($tmp, $tmp {$byte_length - 1} & chr(0xff >> (8 - $bit_length)), $byte_length - 1, 1);
  541.                         return $this->bin2int($tmp);
  542.                 }
  543.  
  544.                 /**
  545.                 * Converts a hex string to bigint string
  546.                 *
  547.                 * @param string $hex
  548.                 * @return string
  549.                 * @access public
  550.                 */
  551.                 function hex2bint($hex) {
  552.                         $result = '0';
  553.                         for ($i = 0; $i < strlen($hex); $i++) {
  554.                                 $result = bcmul($result, '16');
  555.                                 if ($hex[$i] >= '0' && $hex[$i] <= '9') {
  556.                                         $result = bcadd($result, $hex[$i]);
  557.                                 } else if ($hex[$i] >= 'a' && $hex[$i] <= 'f') {
  558.                                                 $result = bcadd($result, '1'.('0' + (ord($hex[$i]) - ord('a'))));
  559.                                         } else if ($hex[$i] >= 'A' && $hex[$i] <= 'F') {
  560.                                                         $result = bcadd($result, '1'.('0' + (ord($hex[$i]) - ord('A'))));
  561.                                                 }
  562.                         }
  563.                         return $result;
  564.                 }
  565.  
  566.                 /**
  567.                 * Converts a hex string to int
  568.                 *
  569.                 * @param string $hex
  570.                 * @return int
  571.                 * @access public
  572.                 */
  573.                 function hex2int($hex) {
  574.                         $result = 0;
  575.                         for ($i = 0; $i < strlen($hex); $i++) {
  576.                                 $result *= 16;
  577.                                 if ($hex[$i] >= '0' && $hex[$i] <= '9') {
  578.                                         $result += ord($hex[$i]) - ord('0');
  579.                                 } else if ($hex[$i] >= 'a' && $hex[$i] <= 'f') {
  580.                                                 $result += 10 + (ord($hex[$i]) - ord('a'));
  581.                                         } else if ($hex[$i] >= 'A' && $hex[$i] <= 'F') {
  582.                                                         $result += 10 + (ord($hex[$i]) - ord('A'));
  583.                                                 }
  584.                         }
  585.                         return $result;
  586.                 }
  587.  
  588.                 /**
  589.                 * Converts a bigint string to the ascii code
  590.                 *
  591.                 * @param string $bigint
  592.                 * @return string
  593.                 * @access public
  594.                 */
  595.                 function bint2char($bigint) {
  596.                         $message = '';
  597.                         while (bccomp($bigint, '0') != 0) {
  598.                                 $ascii = bcmod($bigint, '256');
  599.                                 $bigint = bcdiv($bigint, '256', 0);
  600.                                 $message .= chr($ascii);
  601.                         }
  602.                         return $message;
  603.                 }
  604.  
  605.                 /**
  606.                 * Removes the redundacy in den encrypted string
  607.                 *
  608.                 * @param string $string
  609.                 * @return mixed
  610.                 * @access public
  611.                 */
  612.                 function redundacyCheck($string) {
  613.                         $r1 = substr($string, 0, 2);
  614.                         $r2 = substr($string, 2);
  615.                         $check = $this->hex2int($r1);
  616.                         $value = $r2;
  617.                         $sum = 0;
  618.                         for ($i = 0; $i < strlen($value); $i++) {
  619.                                 $sum += ord($value[$i]);
  620.                         }
  621.                         if ($check == ($sum & 0xFF)) {
  622.                                 return $value;
  623.                         } else {
  624.                                 return NULL;
  625.                         }
  626.                 }
  627.  
  628.                 /**
  629.                 * Decrypts a given string with the $dec_key and the $enc_mod
  630.                 *
  631.                 * @param string $encrypted
  632.                 * @param int $dec_key
  633.                 * @param int $enc_mod
  634.                 * @return string
  635.                 * @access public
  636.                 */
  637.                 function decrypt($encrypted, $dec_key, $enc_mod) {
  638.                         //replaced split with explode
  639.                         $blocks = explode(' ', $encrypted);
  640.                         $result = "";
  641.                         $max = count($blocks);
  642.                         for ($i = 0; $i < $max; $i++) {
  643.                                 $dec = $this->hex2bint($blocks[$i]);
  644.                                 $dec = $this->powmod($dec, $dec_key, $enc_mod);
  645.                                 $ascii = $this->bint2char($dec);
  646.                                 $result .= $ascii;
  647.                         }
  648.                         return $this->redundacyCheck($result);
  649.                 }
  650.  
  651.                 /**
  652.                 * Converts a given decimal string to any base between 2 and 36
  653.                 *
  654.                 * @param string $decimal
  655.                 * @param int $base
  656.                 * @return string
  657.                 */
  658.                 function dec2string($decimal, $base) {
  659.  
  660.                         $string = null;
  661.  
  662.                         $base = (int) $base;
  663.                         if ($base < 2 | $base > 36 | $base == 10) {
  664.                                 echo 'BASE must be in the range 2-9 or 11-36';
  665.                                 exit;
  666.                         }
  667.  
  668.                         $charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  669.  
  670.                         $charset = substr($charset, 0, $base);
  671.  
  672.                         do {
  673.                                 $remainder = bcmod($decimal, $base);
  674.                                 $char = substr($charset, $remainder, 1);
  675.                                 $string = "$char$string";
  676.                                 $decimal = bcdiv(bcsub($decimal, $remainder), $base);
  677.                         } while ($decimal > 0);
  678.  
  679.                         return strtolower($string);
  680.                 }
  681.  
  682.                 function getE() {
  683.                         return $this->_e;
  684.                 }
  685.  
  686.                 function generatePrime($length) {
  687.                         $this->_key_len = intval($length);
  688.                         if ($this->_key_len < 8) {
  689.                                 $this->_key_len = 8;
  690.                         }
  691.  
  692.                         $e = $this->bin2int("\x01\x00\x01");
  693.  
  694.                         $p_len = intval(($this->_key_len + 1) / 2);
  695.                         do {
  696.                                 $p = $this->getPrime($p_len);
  697.                                 $p1 = $this->dec($p);
  698.                                 $tmp = $this->GCD($e, $p1);
  699.                         } while (!$this->isOne($tmp));
  700.  
  701.                         return $p;
  702.                 }
  703.  
  704.         }
  705.  
  706. ?>