Re: PHP version of PGP
Posted: Sun Feb 24, 2008 6:04 pm
I know I never login to that site. I don't even know why they require a login.Ambush Commander wrote:Meh... (Can't be bothered to digout his login for PHP classes)
Code: Select all
<?php
DEFINE('ENCRYPTION_PACKET_SIZE', 40);
class RSA{
/*
* Function for generating keys. Return array where
* $array[0] -> modulo N
* $array[1] -> public key E
* $array[2] -> private key D
* Public key pair is N and E
* Private key pair is N and D
*/
public function generate_keys ($p, $q, $show_debug=0){
$n = bcmul($p, $q);
//m (we need it to calculate D and E)
$m = bcmul(bcsub($p, 1), bcsub($q, 1));
// Public key E
$e = $this->findE($m);
// Private key D
$d = $this->extend($e,$m);
$keys = array ($n, $e, $d); // $n = modulu, $e = public key, $d = private key
if ($show_debug) {
echo "P = $p<br>Q = $q<br><b>N = $n</b> - modulo<br>M = $m<br><b>E = $e</b> - public key<br><b>D = $d</b> - private key<p>";
}
return $keys;
}
/*
* Standard method of calculating D
* D = E-1 (mod N)
* It's presumed D will be found in less then 16 iterations
*/
private function extend ($Ee,$Em) {
$u1 = '1';
$u2 = '0';
$u3 = $Em;
$v1 = '0';
$v2 = '1';
$v3 = $Ee;
while (bccomp($v3, 0) != 0) {
$qq = bcdiv($u3, $v3, 0);
$t1 = bcsub($u1, bcmul($qq, $v1));
$t2 = bcsub($u2, bcmul($qq, $v2));
$t3 = bcsub($u3, bcmul($qq, $v3));
$u1 = $v1;
$u2 = $v2;
$u3 = $v3;
$v1 = $t1;
$v2 = $t2;
$v3 = $t3;
$z = '1';
}
$uu = $u1;
$vv = $u2;
if (bccomp($vv, 0) == -1) {
$inverse = bcadd($vv, $Em);
} else {
$inverse = $vv;
}
return $inverse;
}
/*
* This function return Greatest Common Divisor for $e and $m numbers
*/
private function GCD($e,$m) {
$y = $e;
$x = $m;
while (bccomp($y, 0) != 0) {
// modulus function
$w = bcsub($x, bcmul($y, bcdiv($x, $y, 0)));;
$x = $y;
$y = $w;
}
return $x;
}
/*
* Calculating E under conditions:
* GCD(N,E) = 1 and 1<E<N
*/
private function findE($m){
$e = '3';
if(bccomp($this->GCD($e, $m), '1') != 0){
$e = '5';
$step = '2';
while(bccomp($this->GCD($e, $m), '1') != 0){
$e = bcadd($e, $step);
if($step == '2'){
$step = '4';
}else{
$step = '2';
}
}
}
return $e;
}
/*
* ENCRYPT function returns
* X = M^E (mod N)
*/
public function encrypt ($m, $e, $n) {
$coded = '';
$max = strlen($m);
$packets = ceil($max/ENCRYPTION_PACKET_SIZE);
for($i=0; $i<$packets; $i++){
$packet = substr($m, $i*ENCRYPTION_PACKET_SIZE, ENCRYPTION_PACKET_SIZE);
$code = '0';
for($j=0; $j<ENCRYPTION_PACKET_SIZE; $j++){
$pdata = (isset($packet[$j])) ? $packet[$j] : null;
$code = bcadd($code, bcmul(ord($pdata), bcpow('256',$j)));
}
$code = bcpowmod($code, $e, $n);
$coded .= $code.' ';
}
return trim($coded);
}
/*
ENCRYPT function returns
M = X^D (mod N)
*/
public function decrypt ($c, $d, $n) {
$coded = split(' ', $c);
$message = '';
$max = count($coded);
for($i=0; $i<$max; $i++){
$code = bcpowmod($coded[$i], $d, $n);
while(bccomp($code, '0') != 0){
$ascii = bcmod($code, '256');
$code = bcdiv($code, '256', 0);
$message .= chr($ascii);
}
}
return $message;
}
// Digital Signature
public function sign($message, $d, $n){
$messageDigest = md5($message);
$signature = $this->encrypt($messageDigest, $d, $n, ENCRYPTION_PACKET_SIZE);
return $signature;
}
public function prove($message, $signature, $e, $n){
$messageDigest = $this->decrypt($signature, $e, $n);
if($messageDigest == md5($message)){
return true;
}else{
return false;
}
}
public function signFile($file, $d, $n){
$messageDigest = md5_file($file);
$signature = $this->encrypt($messageDigest, $d, $n, ENCRYPTION_PACKET_SIZE);
return $signature;
}
public function proveFile($file, $signature, $e, $n){
$messageDigest = $this->decrypt($signature, $e, $n);
if($messageDigest == md5_file($file)){
return true;
}else{
return false;
}
}
}
?>
Code: Select all
<pre>
<?php
include 'rsa.class.php';
/*
The keys are:
0:99812541893017455179 - modulo
1:5 - public key
2:19962508374607241957 - private key
*/
error_reporting(0);
$RSA = new RSA();
$message = 'RSA Encryption Test';
$private_key = '19962508374607241957';
$modulo = '99812541893017455179';
$public_key = '5';
echo "Testing with public key to encrypt, private key to decrypt:\n";
$encoded = $RSA->encrypt ($message, $public_key, $modulo);
$decoded = $RSA->decrypt ($encoded, $private_key, $modulo);
echo "Encrypted: $encoded\nDecrypted: $decoded\n";
echo "Testing with private key to encrypt, public key to decrypt:\n";
$encoded = $RSA->encrypt ($message, $private_key, $modulo);
$decoded = $RSA->decrypt ($encoded, $public_key, $modulo);
echo "Encrypted: $encoded\nDecrypted: $decoded\n";
echo "Testing with private key to encrypt, private key to decrypt:\n";
$encoded = $RSA->encrypt ($message, $private_key, $modulo);
$decoded = $RSA->decrypt ($encoded, $private_key, $modulo);
echo "Encrypted: $encoded\nDecrypted: $decoded\n";
echo "Testing with public key to encrypt, public key to decrypt:\n";
$encoded = $RSA->encrypt ($message, $public_key, $modulo);
$decoded = $RSA->decrypt ($encoded, $public_key, $modulo);
echo "Encrypted: $encoded\nDecrypted: $decoded\n";