S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

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 ) . "
"
*/
?>

- 作者: Goooder 2005年05月31日, 星期二 14:47 加入博采


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理