PHP呼叫內容DES加密的SOAP介面
本文以方倍工作室優惠券介面開發為例,介紹PHP下DES加解密及SOAP介面呼叫的實現過程。
一、基礎概念
DES全稱為Data Encryption Standard,即資料加密標準,是一種使用金鑰加密的塊演算法,1976年被美國聯邦政府的國家標準局確定為聯邦資料處理標準(FIPS),隨後在國際上廣泛流傳開來。
DES演算法為密碼體制中的對稱密碼體制,又被稱為美國資料加密標準,是1972年美國IBM公司研製的對稱密碼體制加密演算法。 明文按64位進行分組,金鑰長64位,金鑰事實上是56位參與DES運算(第8、16、24、32、40、48、56、64位是校驗位, 使得每個金鑰都有奇數個1)分組後的明文組和56位的金鑰按位替代或交換的方法形成密文組的加密方法。
SOAP(Simple Object Access Protocol )簡單物件訪問協議是在分散或分散式的環境中交換資訊的簡單的協議,是一個基於XML的協議,它包括四個部分:SOAP封裝(envelop),封裝定義了一個描述訊息中的內容是什麼,是誰傳送的,誰應當接受並處理它以及如何處理它們的框架;SOAP編碼規則(encoding rules),用於表示應用程式需要使用的資料型別的例項; SOAP RPC表示(RPC representation),表示遠端過程呼叫和應答的協定;SOAP繫結(binding),使用底層協議交換資訊。
WSDL(Web Service Description Language)就是描述XML Web服務的標準XML格式,WSDL由Ariba、Intel、IBM和微軟等開發商提出。它用一種和具體語言無關的抽象方式定義了給定Web服務收發的有關操作和訊息。就其定義來說,你還不能把WSDL當作一種物件介面定義語言,例如,CORBA或COM等應用程式體系結構就會用到物件介面定義語言。 WSDL保持協議中立,但它確實內建了繫結SOAP的支援,從而同SOAP建立了不可分割的聯絡。所以,當我在這篇文章中討論WSDL的時候,我會假定你把SOAP作為了你的通訊協議。
SOAP和WSDL雖然是web service的兩大標準,但是兩者並沒有必然的聯絡,都可以獨立使用。它們之間的關係就類似HTTP和Html之間的關係。前者是一種協議,後者是對一個Web Server的描述。
二、PHP下的配置
在php的的配置檔案php.ini中,找到
extension=php_soap.dll
然後將前面的;號去掉,然後重啟web服務
探針檢視環境,需要支援mcrypt和soap
三、DES加解密
Des的類如下,其中iv向量使用固定值。
1 /* 2 方倍工作室3 http://www.fangbei.org 4 */ 5 6 class DES 7 { 8 var $key; 9 var $iv; 10 11 function DES($key) 12 { 13 $this->key = $key; 14 $bytes = array(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 15 $this->iv = $this->bytesToStr($bytes); 16 // $this->iv = mcrypt_create_iv ( mcrypt_get_block_size (MCRYPT_DES, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM ); 17 } 18 19 //加密,返回大寫十六進位制字串 20 function encrypt($str) 21 { 22 $size = mcrypt_get_block_size ( MCRYPT_DES, MCRYPT_MODE_CBC ); 23 $str = $this->pkcs5Pad ( $str, $size ); 24 return strtoupper( bin2hex( mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv ) ) ); 25 } 26 27 //解密 28 function decrypt($str) 29 { 30 $strBin = $this->hex2bin( strtolower( $str ) ); 31 $str = mcrypt_cbc( MCRYPT_DES, $this->key, $strBin, MCRYPT_DECRYPT, $this->iv ); 32 $str = $this->pkcs5Unpad( $str ); 33 return $str; 34 } 35 36 function hex2bin($hexData) 37 { 38 $binData = ""; 39 for($i = 0; $i < strlen ( $hexData ); $i += 2) { 40 $binData .= chr ( hexdec ( substr ( $hexData, $i, 2 ) ) ); 41 } 42 return $binData; 43 } 44 45 function pkcs5Pad($text, $blocksize) 46 { 47 $pad = $blocksize - (strlen ( $text ) % $blocksize); 48 return $text . str_repeat ( chr ( $pad ), $pad ); 49 } 50 51 function pkcs5Unpad($text) 52 { 53 $pad = ord ( $text {strlen ( $text ) - 1} ); 54 if ($pad > strlen ( $text )) 55 return false; 56 if (strspn ( $text, chr ( $pad ), strlen ( $text ) - $pad ) != $pad) 57 return false; 58 return substr ( $text, 0, - 1 * $pad ); 59 } 60 61 function bytesToStr($bytes) 62 { 63 $str = ''; 64 foreach($bytes as $ch) { 65 $str .= chr($ch); 66 } 67 return $str; 68 } 69 }
四、準備入參
首先需要獲得當前訂單號,訂單號為20160322185825271格式。
實現程式碼如下
1 list($millisecond, $second)=explode(' ',microtime()); 2 $timestamp = date("YmdHis",$second); 3 $orderno = $timestamp.substr($millisecond, 2, 3);
然後呼叫DES進行加密
1 $crypt = new DES($desKey); 2 $XMLParam = $crypt->encrypt($XMLData);
明文為
<GetVoucher><machinecode>000000000</machinecode><vtype>VTRMB</vtype><data>10</data><validdays>30</validdays><totalmoney>10</totalmoney><ordercode>20160322185825271</ordercode></GetVoucher>
加密後為
13FDFAF455E7A5516829F73FA6017EC55F54385CD3F15EC0C09FA429F30450504494B024CFA659DCD44A752A84421CDC8010C0B9C1C1B7F027AF1B24F138C08132DF05A923529478B1824BC7533B3A7A2F37F4CA76A8D52E820F6E491A801F9A0B13A69B6ABB4B092143751A7258A4D3935CDD8175091E7F6FE4F3F3964438117621F22B5133681C517C9D4DABE551C323D0D6DB5D563631AD0910D5C51E4DD46133C4FEE3AEC95DFD212F1A70546F7468C1A21168B024CDEA27A097157D08D7
五、PHP呼叫SOAP協議介面
呼叫方法如下
1 try { 2 $client = new SoapClient('http://www.fangbei.org/VoucherService.asmx?WSDL'); 3 $result = $client->GetVoucher(array('XmlParam'=>$XMLParam, 'UserName'=>$UserName,'Sign'=>$Sign)); 4 var_dump($result); 5 $encryptVoucherResult = $result->GetVoucherResult; 6 } catch (SOAPFault $e) { 7 print_r('Exception:'.$e); 8 }
result結果如下
object(stdClass)#2 (1) { ["GetVoucherResult"]=> string(464) "6F036F920E11B1069FC97B5A7CBF5BBB77B58B63980251864C75ECB3D7D34E453B88D50B32B3330F9415B5B54FF03DB082EB5CA9C8C5CCE0664A030BC1BB1541E297B0983E06FDEFCF772F14DA4A0B70F395562BA31BDAED0CA0978680825BA810E8B40FAB24E73562CC782DB897193553FF3724BF86E9863134B9CEA25635D2BCF435B33936896C4E0C257E8CC77D6E017DA4782FE6058CEBABD832EE33E47878B305D89647F8D119C33C24181CCC1A610C286E312B77FF9E02D4077A0C303902DC185D3915BE4BC493661F8212AB98C325C46E242357E7D15A5033956A43F8C651374590D4727F" }
有用的內容為加密的
6F036F920E11B1069FC97B5A7CBF5BBB77B58B63980251864C75ECB3D7D34E453B88D50B32B3330F9415B5B54FF03DB082EB5CA9C8C5CCE0664A030BC1BB1541E297B0983E06FDEFCF772F14DA4A0B70F395562BA31BDAED0CA0978680825BA810E8B40FAB24E73562CC782DB897193553FF3724BF86E9863134B9CEA25635D2BCF435B33936896C4E0C257E8CC77D6E017DA4782FE6058CEBABD832EE33E47878B305D89647F8D119C33C24181CCC1A610C286E312B77FF9E02D4077A0C303902DC185D3915BE4BC493661F8212AB98C325C46E242357E7D15A5033956A43F8C651374590D4727F
對其進行DES解密
1 $decryptVoucherResult = $crypt->decrypt($encryptVoucherResult); 2 var_dump($decryptVoucherResult);
返回內容為XML
<Result><status>1</status><uuid>A5C0CFAE06644038AA53A50DF6CD159C</uuid><extractcode></extractcode><datamatrix>zwH3FAtTwhP7h2zWSe65q7qWdoWqzph5nZ/XUBJP89N/rYIn14k+WxDL+ukchZvKXHdCxs6r6YCBoTIcgW0hgIHg4ULu9C6p</datamatrix></Result>
再將XML轉成PHP陣列,程式碼如下
1 $obj = json_decode(json_encode(simplexml_load_string($decryptVoucherResult)),TRUE); 2 var_dump($obj);
返回陣列如下
array(4) { ["status"]=> string(1) "1" ["uuid"]=> string(32) "A5C0CFAE06644038AA53A50DF6CD159C" ["extractcode"]=> array(0) {} ["datamatrix"]=> string(96) "zwH3FAtTwhP7h2zWSe65q7qWdoWqzph5nZ/XUBJP89N/rYIn14k+WxDL+ukchZvKXHdCxs6r6YCBoTIcgW0hgIHg4ULu9C6p" }