PHP中使用OpenSSL来产生证书加密解密源代码- -
我想这段代码足够简单,没必要写函数说明了吧。
该程序在linux+Apache 2.0 + PHP Version 4.2.2 中运行通过。
大致功能有:1。产生证书;2。使用RSA算法加密解密任意长度数据。
--------------------------------------------------
/*
* Class COPenSSLCrypt
* Author : pigo chu<pigo@ms5.url.com.tw>
* Date : 2004-11-12
* Version : 0.01
* Revision History:
* Lihui Lei 2005-05-18
*/
class COpenSSLCrypt {
/* All member variable is private */
var $publicKey = "";
var $privateKey = "";
var $resourcePubKey = NULL;
var $resourcePriKey = NULL;
var $lastError = "";
var $debugMode = false;
var $keyLength = 64;
var $config = NULL;
/*
* Construct Method
* if $dn is not null , then this class will Generate CSR with $dn
* NOTE $dn is an array like this :
* array(
* "countryName" => "UK",
* "stateOrProvinceName" => "Somerset",
* "localityName" => "Glastonbury",
* "organizationName" => "The Brain Room Limited",
* "organizationalUnitName" => "PHP Documentation Team",
* "commonName" => "Wez Furlong",
* "emailAddress" => "wez@example.com"
* );
*/
function COpenSSLCrypt( $dn=NULL , $passphrase=NULL )
{
if(is_array( $dn ))
{
$this->GenerateKey($dn , $passphrase);
}
}
/*
* Generate CSR and create all key , if $dn is NULL then use default dn to generate
*/
function GenerateKey($dn=NULL , $config= NULL , $passphrase=NULL )
{
if(!$dn)
{
$dn = array(
"countryName" => "CN",
"stateOrProvinceName" => "BEIJING",
"localityName" => "BeiJing",
"organizationName" => "IVT Corporation",
"organizationalUnitName" => "BlueSoleil Group",
"commonName" => "www.bluesolei.com",
"emailAddress" => "support@bluesoleil.com"
);
}
$privkey = openssl_pkey_new();
if (!$config)
{
$config = array(
"digest_alg" => "sha1",
"private_key_bits" => $keyLength,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
"encrypt_key" => false
);
}
$csr = openssl_csr_new($dn, $privkey);
$sscert = openssl_csr_sign($csr, null, $privkey, 365);
echo "
CSR:
";
openssl_csr_export($csr, $csrout);
echo "
Certificate: public key
";
openssl_x509_export($sscert, $certout);
echo "
private key:
";
if($passphrase != NULL){
openssl_pkey_export($privkey, $pkeyout, $passphrase);
}else{
openssl_pkey_export($privkey, $pkeyout);
}
$this->setPublicKey($certout);
$this->setPrivateKey($pkeyout);
}
/*
* Generate CSR and create all key , if $dn is NULL then use default dn to generate
*/
function GenerateKeyToFile($csrFile=NULL, $certFile=NULL, $privkeyFile=NULL )
{
if (!csrFile or !certFile or !privkeyFile)
{
echo "
Please set key files' name and path.
";
return false;
}
if(!$dn)
{
$dn = array(
"countryName" => "CN",
"stateOrProvinceName" => "BEIJING",
"localityName" => "BeiJing",
"organizationName" => "IVT Corporation",
"organizationalUnitName" => "BlueSoleil Group",
"commonName" => "
www.bluesolei.com",
"emailAddress" => "
support@bluesoleil.com"
);
}
$privkey = openssl_pkey_new();
$csr = openssl_csr_new($dn, $privkey);
$sscert = openssl_csr_sign($csr, null, $privkey, 365);
openssl_csr_export_to_file($csr, $csrFile);//and debug_zval_dump($csrout);;
openssl_x509_export_to_file($sscert, $certFile);
if($passphrase != NULL){
openssl_pkey_export_to_file($privkey, $privkeyFile, $passphrase);
}else{
openssl_pkey_export_to_file($privkey, $privkeyFile);
}
return true;
}
function setPublicKey( $key )
{
$this->publicKey = $key;
if( !($this->resourcePubKey = @openssl_get_publickey($key)) )
{
$this->setDebug();
return false;
}
return true;
}
function setPrivateKey( $key , $passphrase="" )
{
$this->privateKey = $key;
if( !($this->resourcePriKey = @openssl_get_privatekey($key , $passphrase)) )
{
$this->setDebug();
return false;
}
return true;
}
function getPublicKey()
{
return $this->publicKey;
}
function getPrivateKey()
{
return $this->privateKey;
}
function encrypt( $source )
{
if(!$this->resourcePubKey)
{
$this->setDebug("decrypt(string) error : No Public Key Resource.\n");
return false;
}
$ret = "";
$len = strlen($source);
echo "The encrypted source length is ". $len;
/*
* Why encrypt each 64 bytes ?
* Because openssl_public_enrypt() can't encrypt large data
* Anyone know why ?
*/
for($i=0;$i<$len;$i+=64)
{
if(!openssl_public_encrypt(substr($source,$i,64),$new_out,$this->resourcePubKey))
{
$errorText = "encrypt(string) error : " . openssl_error_string() . "\n";
$errorText.= "Data Dump : \n" . strtoupper(bin2hex($source)) ."\n";
$this->setDebug( $errorText );
return false;
}
$ret .= $new_out;
}
return $ret;
}
function publicEncrypt_keyFromFile($data, $publicKeyFile, $passphrase=NULL)
{
$fp=fopen($publicKeyFile, "r");
$public_key=fread($fp,8192);
fclose($fp);
// $passphrase is required if your key is encoded (suggested)
if($passphrase != NULL)
$res = openssl_get_publickey($public_key);
else
$res = openssl_get_publickey($public_key);
openssl_public_encrypt($data, $encrypted, $res);
return $encrypted;
}
function privateDecrypt_keyFromFile($data, $privateKeyFile, $passphrase=NULL)
{
$fp=fopen ($privateKeyFile,"r");
$private_key=fread($fp,8192);
fclose($fp);
if($passphrase != NULL)
openssl_get_privatekey($private_key, $passphrase);
else
openssl_get_privatekey($private_key);
openssl_private_decrypt($data, $decrpted, $private_key);
return $decrpted;
}
function decrypt( $cryptedData )
{
if(!$this->resourcePriKey)
{
$this->setDebug("decrypt(string) error : No Private Key Resource.\n");
return false;
}
$ret = "";
$len = strlen($cryptedData);
/*
* Why decrypt each 128 bytes?
* Because openssl_private_decrypt can't decrypt large data.
* And when use openssl_public_enrypt to crypt data . It will create a 128 bytes string(Encoded)
*/
for($i=0;$i<$len;$i+=128)
{
if(!openssl_private_decrypt(substr($cryptedData,$i,128),$new_out,$this->resourcePriKey))
{
$errorText = "decrypt(string) error : " . openssl_error_string() . "\n";
$errorText.= "Data Dump : \n" . strtoupper(bin2hex($cryptedData)) ."\n";
$this->setDebug( $errorText );
return false;
}
$ret .= $new_out;
}
return $ret;
}
function setKeyLength( $bitNum=64 )
{
$keyLength = $bitNum;
}
function getLastError()
{
return $this->lastError;
}
function setDebugMode( $bl=false )
{
$this->debugMode = $bl;
}
function setDebug( $msg="" )
{
if(!$msg)
$this->lastError = openssl_error_string();
else
$this->lastError = $msg;
if( $this->debugMode )
echo $this->lastError;
}
}
//echo phpinfo();
echo "
Openssl Encrypt/Decrypt Example:
";
// use a large data for test
$testStr= <<
This a php script, you cannot see it.
EOT;
// Now I am server
$server_ssl = new COpenSSLCrypt;
$server_ssl->setDebugMode(true);
//Generate Key File.
$ret = $server_ssl->GenerateKeyToFile("/home/test/cert.csr",
"/home/test/cert.pem",
"/home/test/privkey.pem");
if (!$ret)
echo "
Error to generate key.";
echo "
The plain text is:
".$testStr;
// Start Encrpt process at the server end.
echo "
The encrpyted result is:
";
$cryptedData = $server_ssl->publicEncrypt_keyFromFile($testStr, "/home/test/cert.pem");
echo $cryptedData;
// Start Decrpt process at the client end.
echo "
The decrpyted result is:
";
$decryptedData = $server_ssl->privateDecrypt_keyFromFile($cryptedData, "/home/test/privkey.pem");
echo $decryptedData;
/*// Now I ma client
$client_ssl = new COpenSSLCrypt;
$client_ssl->setDebugMode(true);
$client_ssl->GenerateKeyToFile("/home/test/cert.csr",
"/home/test/cert.pem",
"/home/test/privkey.pem");
// Now I am server , and client send a public key to me
$client_public_key = $client_ssl->getPublicKey();
$server_ssl->setPublicKey( $client_public_key );
$cryptedText = $server_ssl->encrypt($testStr);
// Now I am client , and I will decrypt $cryptedText
echo "The encrypted length is ". strlen($cryptedText) . "
";
$dumpData = strtoupper(bin2hex($cryptedText));
echo "Dump CryptedText :". $dumpData. "
";
echo "The encrypted length is ". strlen($dumpData) . "
";
echo "Decrypt Text : ". $client_ssl->decrypt( $cryptedText ) . "
"
// Now I am server
$server_ssl = new COpenSSLCrypt;
$server_ssl->setDebugMode(true);
// Now I ma client
$client_ssl = new COpenSSLCrypt;
$client_ssl->setDebugMode(true);
$client_ssl->GenerateKeyToFile("/home/test/cert.pem",
"/home/test/cert.pem",
"/home/test/privkey.pem");
// Now I am server , and client send a public key to me
$client_public_key = $client_ssl->getPublicKey();
$server_ssl->setPublicKey( $client_public_key );
$cryptedText = $server_ssl->encrypt($testStr);
// Now I am client , and I will decrypt $cryptedText
echo "The encrypted length is ". strlen($cryptedText) . "
";
$dumpData = strtoupper(bin2hex($cryptedText));
echo "Dump CryptedText :". $dumpData. "
";
echo "The encrypted length is ". strlen($dumpData) . "
";
echo "Decrypt Text : ". $client_ssl->decrypt( $cryptedText ) . "
"
*/
?>