1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning PHP and MySQL E-Commerce From Novice to Professional phần 8 ppt

74 312 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 74
Dung lượng 1,61 MB

Nội dung

// Pack SymmetricCrypt::_msHexaIv into a binary string $binary_iv = pack('H*', self::$_msHexaIv); The conversion is done using PHP’s pack() function (learn more about it at http://www.php.net/pack). The call to mcrypt_encrypt() follows: // Encrypt $plainString $binary_encrypted_string = mcrypt_encrypt( self::$_msCipherAlgorithm, self::$_msSecretKey, $plainString, MCRYPT_MODE_CBC, $binary_iv); This is the call that performs the actual encryption. Its parameters are obvious, and you can find more detail about the mcrypt_encrypt() function at http://www.php.net/mcrypt. The MCRYPT_MODE_CBC specifies the “cipher block chaining” encryption method; this method uses a chaining mechanism in which the encryption of each block of data depends on the encryption results of preceding blocks, except for the first block in which the IV is used instead. At the end, the encrypted string is transformed into hexadecimal format, which is easier to work with (for example, to save in the database or in a configuration file): // Convert $binary_encrypted_string to hexadecimal format $hexa_encrypted_string = bin2hex($binary_encrypted_string); The Decrypt() method is similar to the Encrypt() method. First you need the IV to be in a binary form (the same first step you took in the Encrypt() method). As the Encrypt() method returns the encrypted string as a hexadecimal string, the input parameter of Decrypt() is also a hexadecimal string. You must convert this string to a byte array, which is the format that mcrypt_decrypt() needs: // Convert string in hexadecimal to byte array $binary_encrypted_string = pack('H*', $encryptedString); // Decrypt $binary_encrypted_string $decrypted_string = mcrypt_decrypt( self::$_msCipherAlgorithm, self::$_msSecretKey, $binary_encrypted_string, MCRYPT_MODE_CBC, $binary_iv); return $decrypted_string; The test_encryption.php test file for this class simply encrypts and decrypts data, demonstrating that things are working properly. The code for this is very simple, so we won’t detail it here. Now that you have the SymmetricCrypt class code, the last step in creating the security-related classes is to add the SecureCard class. CHAPTER 16 ■ MANAGING CUSTOMER DETAILS 489 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 489 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Storing Credit Cart Information Using the SecureCard Class In the following exercise, you’ll build the SecureCard class, which represents the credit card of a customer. This class will use the functionality you implemented in the previous two exercises to ensure that its data will be stored securely in the database. Exercise: Implementing the SecureCard Class 1. Create a new file named secure_card.php in the business folder, and add the following code to it: <?php // Represents a credit card class SecureCard { // Private members containing credit card's details private $_mIsDecrypted = false; private $_mIsEncrypted = false; private $_mCardHolder; private $_mCardNumber; private $_mIssueDate; private $_mExpiryDate; private $_mIssueNumber; private $_mCardType; private $_mEncryptedData; private $_mXmlCardData; // Class constructor public function __construct() { // Nothing here } // Decrypt data public function LoadEncryptedDataAndDecrypt($newEncryptedData) { $this->_mEncryptedData = $newEncryptedData; $this->DecryptData(); } // Encrypt data public function LoadPlainDataAndEncrypt($newCardHolder, $newCardNumber, $newIssueDate, $newExpiryDate, $newIssueNumber, $newCardType) { $this->_mCardHolder = $newCardHolder; $this->_mCardNumber = $newCardNumber; $this->_mIssueDate = $newIssueDate; CHAPTER 16 ■ MANAGING CUSTOMER DETAILS490 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 490 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com $this->_mExpiryDate = $newExpiryDate; $this->_mIssueNumber = $newIssueNumber; $this->_mCardType = $newCardType; $this->EncryptData(); } // Create XML with credit card information private function CreateXml() { // Encode card details as XML document $xml_card_data = &$this->_mXmlCardData; $xml_card_data = new DOMDocument(); $document_root = $xml_card_data->createElement('CardDetails'); $child = $xml_card_data->createElement('CardHolder'); $child = $document_root->appendChild($child); $value = $xml_card_data->createTextNode($this->_mCardHolder); $value = $child->appendChild($value); $child = $xml_card_data->createElement('CardNumber'); $child = $document_root->appendChild($child); $value = $xml_card_data->createTextNode($this->_mCardNumber); $value = $child->appendChild($value); $child = $xml_card_data->createElement('IssueDate'); $child = $document_root->appendChild($child); $value = $xml_card_data->createTextNode($this->_mIssueDate); $value = $child->appendChild($value); $child = $xml_card_data->createElement('ExpiryDate'); $child = $document_root->appendChild($child); $value = $xml_card_data->createTextNode($this->_mExpiryDate); $value = $child->appendChild($value); $child = $xml_card_data->createElement('IssueNumber'); $child = $document_root->appendChild($child); $value = $xml_card_data->createTextNode($this->_mIssueNumber); $value = $child->appendChild($value); $child = $xml_card_data->createElement('CardType'); $child = $document_root->appendChild($child); $value = $xml_card_data->createTextNode($this->_mCardType); $value = $child->appendChild($value); $document_root = $xml_card_data->appendChild($document_root); } CHAPTER 16 ■ MANAGING CUSTOMER DETAILS 491 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 491 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com // Extract information from XML credit card data private function ExtractXml($decryptedData) { $xml = simplexml_load_string($decryptedData); $this->_mCardHolder = (string) $xml->CardHolder; $this->_mCardNumber = (string) $xml->CardNumber; $this->_mIssueDate = (string) $xml->IssueDate; $this->_mExpiryDate = (string) $xml->ExpiryDate; $this->_mIssueNumber = (string) $xml->IssueNumber; $this->_mCardType = (string) $xml->CardType; } // Encrypts the XML credit card data private function EncryptData() { // Put data into XML doc $this->CreateXml(); // Encrypt data $this->_mEncryptedData = SymmetricCrypt::Encrypt($this->_mXmlCardData->saveXML()); // Set encrypted flag $this->_mIsEncrypted = true; } // Decrypts XML credit card data private function DecryptData() { // Decrypt data $decrypted_data = SymmetricCrypt::Decrypt($this->_mEncryptedData); // Extract data from XML $this->ExtractXml($decrypted_data); // Set decrypted flag $this->_mIsDecrypted = true; } public function __get($name) { if ($name == 'EncryptedData') { if ($this->_mIsEncrypted) return $this->_mEncryptedData; else throw new Exception('Data not encrypted'); } CHAPTER 16 ■ MANAGING CUSTOMER DETAILS492 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 492 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com elseif ($name == 'CardNumberX') { if ($this->_mIsDecrypted) return 'XXXX-XXXX-XXXX-' . substr($this->_mCardNumber, strlen($this->_mCardNumber) - 4, 4); else throw new Exception('Data not decrypted'); } elseif (in_array($name, array ('CardHolder', 'CardNumber', 'IssueDate', 'ExpiryDate', 'IssueNumber', 'CardType'))) { $name = '_m' . $name; if ($this->_mIsDecrypted) return $this->$name; else throw new Exception('Data not decrypted'); } else { throw new Exception('Property ' . $name . ' not found'); } } } ?> 2. Create a new file named test_card.php file in the tshirtshop folder: <?php require_once 'include/config.php'; require_once BUSINESS_DIR . 'symmetric_crypt.php'; require_once BUSINESS_DIR . 'secure_card.php'; $card_holder = 'John Doe'; $card_number = '1234567890123456'; $expiry_date = '01/09'; $issue_date = '01/06'; $issue_number = 100; $card_type = 'Mastercard'; echo '<br />Credit card data:<br />' . $card_holder . ', ' . $card_number . ', ' . $issue_date . ', ' . $expiry_date . ', ' . $issue_number . ', ' . $card_type . '<br />'; $credit_card = new SecureCard(); CHAPTER 16 ■ MANAGING CUSTOMER DETAILS 493 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 493 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com try { $credit_card->LoadPlainDataAndEncrypt($card_holder, $card_number, $issue_date, $expiry_date, $issue_number, $card_type); $encrypted_data = $credit_card->EncryptedData; } catch(Exception $e) { echo '<font color="red">Exception: ' . $e->getMessage() . '</font>'; exit(); } echo '<br />Encrypted data:<br />' . $encrypted_data . '<br />'; $our_card = new SecureCard(); try { $our_card->LoadEncryptedDataAndDecrypt($encrypted_data); echo '<br/>Decrypted data:<br/>' . $our_card->CardHolder . ', ' . $our_card->CardNumber . ', ' . $our_card->IssueDate . ', ' . $our_card->ExpiryDate . ', ' . $our_card->IssueNumber . ', ' . $our_card->CardType; } catch(Exception $e) { echo '<font color="red">Exception: ' . $e->getMessage() . '</font>'; exit(); } ?> 3. Load test_card.php file in your favorite browser to see the results (see Figure 16-3). You can change the data from this file as you want. CHAPTER 16 ■ MANAGING CUSTOMER DETAILS494 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 494 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Figure 16-3. Encrypting and decrypting credit card information How It Works: The SecureCard Class There’s a bit more code here than in previous examples, but it’s all quite simple. First you have the private member variables to hold the card details as individual strings, as an encrypted string, and in an intermediate XML docu- ment. You also have Boolean flags indicating whether the data has been successfully encrypted or decrypted: <?php // Represents a credit card class SecureCard { // Private members containing credit card's details private $_mIsDecrypted = false; private $_mIsEncrypted = false; private $_mCardHolder; private $_mCardNumber; private $_mIssueDate; private $_mExpiryDate; private $_mIssueNumber; private $_mCardType; private $_mEncryptedData; private $_mXmlCardData; Next you have two important public methods. Public members are part of the public interface of the class, which provides the functionality for external clients. LoadEncryptedDataAndDecrypt() receives an encrypted string and performs the decryption; LoadPlainDataAndEncrypt() receives the credit card data in plain format and encrypts it: CHAPTER 16 ■ MANAGING CUSTOMER DETAILS 495 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 495 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com // Decrypt data public function LoadEncryptedDataAndDecrypt($newEncryptedData) { $this->_mEncryptedData = $newEncryptedData; $this->DecryptData(); } // Encrypt data public function LoadPlainDataAndEncrypt($newCardHolder, $newCardNumber, $newIssueDate, $newExpiryDate, $newIssueNumber, $newCardType) { $this->_mCardHolder = $newCardHolder; $this->_mCardNumber = $newCardNumber; $this->_mIssueDate = $newIssueDate; $this->_mExpiryDate = $newExpiryDate; $this->_mIssueNumber = $newIssueNumber; $this->_mCardType = $newCardType; $this->EncryptData(); } The main work is carried out by the private EncryptData() and DecryptData() methods, which you’ll come to shortly. First you have two utility methods for packaging and unpackaging data in XML format (which makes it easier to get at the bits you want when exchanging data with the encrypted format). XML is a very powerful, tag-based format in which you can store various kinds of information. The SecureCard class stores a customer’s credit card data in a structure like the following: <?xml version="1.0"?> <CardDetails> <CardHolder>John Doe</CardHolder> <CardNumber>1234567890123456</CardNumber> <IssueDate>01/06</IssueDate> <ExpiryDate>01/09</ExpiryDate> <IssueNumber>100</IssueNumber> <CardType>Mastercard</CardType> </CardDetails> The DOMDocument class is used to work with XML data; this class knows how to create, read, and manipulate XML documents without much effort from the developer. The Document Object Model (DOM) is the most important and versatile tree-model XML-parsing application programming interface (API). ■Tip The World Wide Web Consortium manages the DOM standard; its official web page is http://www.w3.org/DOM/. CHAPTER 16 ■ MANAGING CUSTOMER DETAILS496 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 496 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com With the new PHP 5 DOM extension, reading, creating, editing, saving, and searching XML documents from PHP has never been easier. The DOM extension in PHP 5 was entirely rewritten from scratch to fully comply with the DOM specifications. You can see this extension in action in the CreateXml() method, which creates an XML document with the structure shown earlier by creating nodes and setting their values: // Create XML with credit card information private function CreateXml() { // Encode card details as XML document $xml_card_data = &$this->_mXmlCardData; $xml_card_data = new DOMDocument(); $document_root = $xml_card_data->createElement('CardDetails'); $child = $xml_card_data->createElement('CardHolder'); $child = $document_root->appendChild($child); $value = $xml_card_data->createTextNode($this->_mCardHolder); $value = $child->appendChild($value); $document_root = $xml_card_data->appendChild($document_root); } For reading the XML document, you can use the DOMDocument object, but in the ExtractXml() method, we preferred to use a new and unique feature of PHP 5 called SimpleXML. Although less complex and powerful than DOMDocument, the SimpleXML extension makes parsing XML data a piece of cake by transforming it into a data structure you can simply iterate through: // Extract information from XML credit card data private function ExtractXml($decryptedData) { $xml = simplexml_load_string($decryptedData); $this->_mCardHolder = (string) $xml->CardHolder; $this->_mCardNumber = (string) $xml->CardNumber; $this->_mIssueDate = (string) $xml->IssueDate; $this->_mExpiryDate = (string) $xml->ExpiryDate; $this->_mIssueNumber = (string) $xml->IssueNumber; $this->_mCardType = (string) $xml->CardType; } The EncryptData() method starts by using the CreateXml() method to package the details supplied in the SecureCard constructor into XML format: // Encrypts the XML credit card data private function EncryptData() { // Put data into XML doc $this->CreateXml(); CHAPTER 16 ■ MANAGING CUSTOMER DETAILS 497 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 497 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Next, the XML string contained in the resultant XML document is encrypted into a single string and stored in the $_mEncryptedData member: // Encrypt data $this->_mEncryptedData = SymmetricCrypt::Encrypt($this->_mXmlCardData->saveXML()); Finally, the $_mIsEncrypted flag is set to true to indicate that the credit card data has been encrypted: // Set encrypted flag $this->_mIsEncrypted = true; } The DecryptData() method gets the XML credit card data from its encrypted form, decrypts it, and populates class attributes with the ExtractXml() method: // Decrypts XML credit card data private function DecryptData() { // Decrypt data $decrypted_data = SymmetricCrypt::Decrypt($this->_mEncryptedData); // Extract data from XML $this->ExtractXml($decrypted_data); // Set decrypted flag $this->_mIsDecrypted = true; } Next, we define a few properties for the class. Starting with PHP 5, you can define a public __get() function that is called automatically whenever you try to call a method or read a member that isn’t defined in the class. Take, for example, this code snippet: $card = new SecureCard(); $encrypted = $card->EncryptedData; Because there’s no member named EncryptedData in the SecureCard class, the __get() function is called. In __get(), you can check which property is accessed, and you can include code that returns the value for that property. This technique is particularly useful when you want to define “virtual” members of the class whose val- ues need to be calculated on the spot as an alternative to using get functions such as GetEncryptedData(). In our case, the __get() function handles eight “virtual” members. The first is EncryptedData, whose value is returned only if $_mIsEncrypted is true: public function __get($name) { if ($name == 'EncryptedData') { if ($this->_mIsEncrypted) return $this->_mEncryptedData; CHAPTER 16 ■ MANAGING CUSTOMER DETAILS498 8644ch16FINAL.qxd 1/30/08 12:47 PM Page 498 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]... creates the customer_get_customer stored procedure in your tshirtshop database: Create customer_get_customer stored procedure CREATE PROCEDURE customer_get_customer(IN inCustomerId INT) BEGIN SELECT customer_id, name, email, password, credit_card, address_1, address_2, city, region, postal_code, country, shipping_region_id, day_phone, eve_phone, mob_phone FROM customer WHERE customer_id = inCustomerId;... $_SESSION['tshirtshop_customer_id'] = $customer_id; return $customer_id; } 86 44ch16FINAL.qxd 1/30/ 08 12:47 PM Page 507 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com CHAPTER 16 ■ MANAGING CUSTOMER DETAILS public static function Get($customerId = null) { if (is_null($customerId)) $customerId = self::GetCurrentCustomerId(); // Build the SQL query $sql = 'CALL customer_get_customer(:customer_id)';... href="{$obj->mLinkToRegisterCustomer}">Register user 2 Create a new presentation object file named customer_login .php in the presentation folder, and add the following to it: < ?php class CustomerLogin { // Public stuff public $mErrorMessage; public $mLinkToLogin; public $mLinkToRegisterCustomer; public $mEmail = ''; 86 44ch16FINAL.qxd 1/30/ 08 12:47 PM Page 511 Simpo PDF Merge and Split... CUSTOMER DETAILS 6 Execute this code, which creates the customer_update_credit_card stored procedure in your tshirtshop database: Create customer_update_credit_card stored procedure CREATE PROCEDURE customer_update_credit_card( IN inCustomerId INT, IN inCreditCard TEXT) BEGIN UPDATE customer SET credit_card = inCreditCard WHERE customer_id = inCustomerId; END$$ The customer_update_credit_card stored... customer_id = inCustomerId; END$$ The customer_update_address stored procedure updates the customer’s address in the database 86 44ch16FINAL.qxd 1/30/ 08 12:47 PM Page 505 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com CHAPTER 16 ■ MANAGING CUSTOMER DETAILS Implementing the Business Tier In the business folder, create a new file named customer .php that will contain the Customer... customer .php that will contain the Customer class The Customer class is a little longer and mostly accesses the data tier functionality to respond to requests that come from the presentation tier Write the following code in the business/customer .php file: < ?php // Business tier class that manages customer accounts functionality class Customer { // Checks if a customer_id exists in session public static function... function IsValid($email, $password) { $customer = self::GetLoginInfo($email); if (empty ($customer['customer_id'])) return 2; $customer_id = $customer['customer_id']; $hashed_password = $customer['password']; 505 86 44ch16FINAL.qxd 1/30/ 08 12:47 PM Page 506 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 506 CHAPTER 16 ■ MANAGING CUSTOMER DETAILS if (PasswordHasher::Hash($password)... forget to set the $$ delimiter before executing the code of each step 2 Execute this code, which creates the customer_get_login_info stored procedure in your tshirtshop database: Create customer_get_login_info stored procedure CREATE PROCEDURE customer_get_login_info(IN inEmail VARCHAR(100)) BEGIN SELECT customer_id, password FROM customer WHERE email = inEmail; END$$ 86 44ch16FINAL.qxd 1/30/ 08 12:47... WHERE customer_id = inCustomerId; END$$ The customer_get_customer stored procedure returns full customer details for a given customer ID 5 Execute the following code, which creates the customer_update_account stored procedure in your tshirtshop database: Create customer_update_account stored procedure CREATE PROCEDURE customer_update_account(IN inCustomerId INT, IN inName VARCHAR(50), IN inEmail... public $mLinkToAccountDetails; public $mLinkToCreditCardDetails; public $mLinkToAddressDetails; public $mLinkToLogout; public $mSelectedMenuItem; 86 44ch16FINAL.qxd 1/30/ 08 12:47 PM Page 513 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com CHAPTER 16 ■ MANAGING CUSTOMER DETAILS // Class constructor public function construct() { $this->mLinkToAccountDetails = Link::ToAccountDetails(); . day_phone, eve_phone, mob_phone FROM customer WHERE customer_id = inCustomerId; END$$ The customer_get_customer stored procedure returns full customer details for a given customer ID. 5. Execute the. the query and get the customer_id $customer_id = DatabaseHandler::GetOne($sql, $params); if ($addAndLogin) $_SESSION['tshirtshop_customer_id'] = $customer_id; return $customer_id; } CHAPTER. to add the SecureCard class. CHAPTER 16 ■ MANAGING CUSTOMER DETAILS 489 86 44ch16FINAL.qxd 1/30/ 08 12:47 PM Page 489 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Storing

Ngày đăng: 12/08/2014, 10:21

TỪ KHÓA LIÊN QUAN