台灣最大程式設計社群網站
線上人數
824
 
會員總數:245973
討論主題:189551
歡迎您免費加入會員
討論區列表 >> PHP >> (轉載) 利用openSSL完成加解密
[]  
[我要回覆]
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
(轉載) 利用openSSL完成加解密
價值 : 10 QP  點閱數:3483 回應數:0
樓主

豆豆
初學者
476 175
1382 595
發送站內信

來源:pigo.pigo.idv.tw

<? 
/* 
* Class COPenSSLCrypt 
* Author  : pigo chu<pigo@ms5.url.com.tw> 
* Date    : 2004-11-12 
* Version : 0.01 
*/ 

class COpenSSLCrypt { 

    /* All member variable is private */ 
    var $publicKey  = ""; 
    var $privateKey = ""; 
    var $resourcePubKey = NULL; 
    var $resourcePriKey = NULL; 
    var $lastError = ""; 
    var $debugMode = false; 

    /* 
     * 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 , $passphrase=NULL ) 
    { 
        if(!$dn) 
        { 
            $dn = array( 
                "countryName" => "TW", 
                "stateOrProvinceName" => "PIGO", 
                "localityName" => "Taipei", 
                "organizationName" => "Ha", 
                "organizationalUnitName" => "PIGO Home", 
                "commonName" => "www.pigo.idv.tw", 
                "emailAddress" => "pigo@ms5.com" 
            ); 
        } 
        $privkey = openssl_pkey_new(); 
        $csr = openssl_csr_new($dn, $privkey); 
        $sscert = openssl_csr_sign($csr, null, $privkey, 365); 
        openssl_csr_export($csr, $csrout); 
        openssl_x509_export($sscert, $certout); 
        if($passphrase != NULL) 
            openssl_pkey_export($privkey, $pkeyout, $passphrase); 
        else 
            openssl_pkey_export($privkey, $pkeyout); 
        $this->setPublicKey($certout); 
        $this->setPrivateKey($pkeyout); 
    } 



    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); 
        /* 
         * 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 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 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 "Emulate Openssl:<br>"; 

// use a large data for test 
$testStr= <<<EOT 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 TEST 12345 
EOT; 


// 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->GenerateKey(); 

// 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 "Dump CryptedText :" .strtoupper(bin2hex($cryptedText)) . "<br>"; 
echo "Decrypt Text : ". $client_ssl->decrypt( $cryptedText ) . "<br>" 
*/ 
?>

搜尋相關Tags的文章: [ SSL ] , [ 加密 ] , [ 解密 ] ,
本篇文章發表於2005-03-10 11:00
目前尚無任何回覆
   

回覆
如要回應,請先登入.