2016-10-21 7 views
0

올해 4 월에 내 웹 사이트 v.3 Sagepay 업그레이드를 완료했으며 정상적으로 작동합니다.Sagepay 웹 사이트에 암호화 코드를 제출하는 웹 사이트가 작동했지만 서버 PHP 업그레이드 후 오류가 발생했습니다.

하지만 이제 내 웹 호스팅 제공 업체가 PHP 버전을 5.2.4에서 5.5.9로 업그레이드하여 웹 사이트의 주요 중단을 초래했습니다.

저는 (동적 제품 목록 및 세부 정보 페이지가 모두 비어있는 것처럼) 가장 극적인 문제를 해결할 수 있었으며 Sagepay에 제출하는 데 실패했습니다.

제출 버튼을 누르면, Sagepay에 대한 제출의 암호화를 처리하는 functions.php 페이지의 대부분의 코드를 표시하는 텍스트 문자열이 포함 된 페이지가 표시됩니다. Sagepay의 응답을 해독합니다. (다행히 문자열에는 암호화 암호가 포함되지 않습니다.) 제출은 물론 진행될 수 없습니다.

이 페이지의 코드는 이전 버전의 SagePay 설명서와 혼합되거나 버전 3의 업데이트 된 스크립트로 대체되었습니다. 사실 여기에서 Stackoverflow의 기여자로부터 암호화 예제를 주로 활용했습니다. 여기

페이지에 코드입니다 (내가 탈락해야하는 경우 미안 오전 Sagepay를에서 주로 어떤 주석 -은 여기 게시물 눈살을 찌푸리게 만약 내가 확실하지 않다) :

//************ NEW CRYPT STUFF COPIED FRON SAGEPAY KIT util.php 
//DH added class definition as shown in stackoverflow page - trying to fix error when run, on line static private function etc 

class DHclassInFunc{ 

/** 
* PHP's mcrypt does not have built in PKCS5 Padding, so we use this. 
* 
* @param string $input The input string. 
* 
* @return string The string with padding. 
*/ 
static protected function addPKCS5Padding($input) 
{ 
$blockSize = 16; 
$padd = ""; 

// Pad input to an even block size boundary. 
$length = $blockSize - (strlen($input) % $blockSize); 
for ($i = 1; $i <= $length; $i++) 
{ 
$padd .= chr($length); 
} 
return $input . $padd; 
} 

/** 
* Remove PKCS5 Padding from a string. 
* 
* @param string $input The decrypted string. 
* 
* @return string String without the padding. 
* @throws SagepayApiException 
*/ 
static protected function removePKCS5Padding($input) 
{ 
$blockSize = 16; 
$padChar = ord($input[strlen($input) - 1]); 

/* Check for PadChar is less then Block size */ 
if ($padChar > $blockSize) 
{ 
throw new SagepayApiException('Invalid encryption string'); 
} 
/* Check by padding by character mask */ 
if (strspn($input, chr($padChar), strlen($input) - $padChar) !=   $padChar) 
{ 
throw new SagepayApiException('Invalid encryption string'); 
} 

$unpadded = substr($input, 0, (-1) * $padChar); 
/* Chech result for printable characters */ 
if (preg_match('/[[:^print:]]/', $unpadded)) 
{ 
throw new SagepayApiException('Invalid encryption string'); 
} 
return $unpadded; 
} 

/** 
* Encrypt a string ready to send to SagePay using encryption key. 
* 
* @param string $string The unencrypyted string. 
* @param string $key  The encryption key. 
* 
* @return string The encrypted string. 
*/ 
static public function encryptAes($string, $key) 
{ 
// AES encryption, CBC blocking with PKCS5 padding then HEX encoding. 
// Add PKCS5 padding to the text to be encypted. 
$string = self::addPKCS5Padding($string); 

// Perform encryption with PHP's MCRYPT module. 
$crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $key); 

// Perform hex encoding and return. 
return "@" . strtoupper(bin2hex($crypt)); 
} 

/** 
* Decode a returned string from SagePay. 
* 
* @param string $strIn   The encrypted String. 
* @param string $password  The encyption password used to encrypt the string. 
* 
* @return string The unecrypted string. 
* @throws SagepayApiException 
*/ 
static public function decryptAes($strIn, $password) 
{ 
    // HEX decoding then AES decryption, CBC blocking with PKCS5 padding. 
    // Use initialization vector (IV) set from $str_encryption_password. 
    $strInitVector = $password; 

    // Remove the first char which is @ to flag this is AES encrypted and HEX decoding. 
    $hex = substr($strIn, 1); 

    // Throw exception if string is malformed 
    if (!preg_match('/^[0-9a-fA-F]+$/', $hex)) 
    { 
     throw new SagepayApiException('Invalid encryption string'); 
    } 
    $strIn = pack('H*', $hex); 

    // Perform decryption with PHP's MCRYPT module. 
    $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, $strIn, MCRYPT_MODE_CBC, $strInitVector); 
    return self::removePKCS5Padding($string); 
} 
} 

/* The getToken function.                          ** 
** NOTE: A function of convenience that extracts the value from the  "name=value&name2=value2..." VSP reply string ** 
** Works even if one of the values is a URL containing the & or = signs. */ 

function getToken($thisString) { 

// List the possible tokens 
$Tokens = array(
"Status", 
"StatusDetail", 
"VendorTxCode", 
"VPSTxId", 
"TxAuthNo", 
"Amount", 
"AVSCV2", 
"AddressResult", 
"PostCodeResult", 
"CV2Result", 
"GiftAid", 
"3DSecureStatus", 
"CAVV"); 

// Initialise arrays 
$output = array(); 
$resultArray = array(); 

// Get the next token in the sequence 
for ($i = count($Tokens)-1; $i >= 0 ; $i--){ 
// Find the position in the string 
$start = strpos($thisString, $Tokens[$i]); 
// If it's present 
if ($start !== false){ 
// Record position and token name 
$resultArray[$i]->start = $start; 
$resultArray[$i]->token = $Tokens[$i]; 
} 
} 

// Sort in order of position 
sort($resultArray); 

// Go through the result array, getting the token values 
for ($i = 0; $i<count($resultArray); $i++){ 
// Get the start point of the value 
$valueStart = $resultArray[$i]->start + strlen($resultArray[$i]->token) + 1; 
// Get the length of the value 
if ($i==(count($resultArray)-1)) { 
$output[$resultArray[$i]->token] = substr($thisString, $valueStart); 
} else { 
$valueLength = $resultArray[$i+1]->start - $resultArray[$i]->start -  strlen($resultArray[$i]->token) - 2; 
$output[$resultArray[$i]->token] = substr($thisString, $valueStart, $valueLength); 
}  
} 

// Return the ouput array 
return $output; 

} 

// Randomise based on time 
function randomise() { 
list($usec, $sec) = explode(' ', microtime()); 
return (float) $sec + ((float) $usec * 100000); 
} 
?> 

I 내가 관련이 있다고 생각하는이 페이지의 이전 문제를 언급하고 아마도 문제의 근원을 가리키는 데 도움이 될 것입니다. -

새로운 PHP 버전으로 서버를 시험 사용 한 후 - 제품이 모두 사라진 것을 보여줍니다. 이전 버전의 PHP로 되돌 렸습니다 (테스트 기간 동안 되돌리기가 허용되었지만 지금은 업그레이드가 최종적입니다). 복귀 후 사이트 표시가 정상으로 돌아 왔지만 Sagepay 기능이 제대로 작동하지 않습니다.이 경우 Submit to Page는 정상적으로 작동했지만 function.php 페이지를 눌렀을 때 Response가 실패했습니다.

이 경우 eror 메시지 새로운 SagepayApiException ('잘못된 암호화 문자열')을 던져 ';' 페이지 스크립트의 반환 부분에있는 아래 세그먼트에서

특히 내 최소한의 PHP는 전반적인 기술 및 디버깅
// Throw exception if string is malformed 
if (!preg_match('/^[0-9a-fA-F]+$/', $hex)) 
{ 
throw new SagepayApiException('Invalid encryption string'); 
} 
$strIn = pack('H*', $hex); 

, 실제로는 뭔가 오히려 자체에 결함이있는 반환 된 토굴 문자열보다, 잘못 가고 있었다 직전에 몇 줄 것을 나에게 보였다.

반송 오류를 표시 한 페이지의 URL에서 암호화 문자열을 복사 한 다음 반환 문자열을 $ hex 및 스크립트 대신 입력으로 하드 코딩하여 preg-match 함수의 일치 문자열에 대해 테스트했습니다 오류 함정을 넘어서서 대신 다른 행의 인스턴스에서 중지되었습니다. '새 SagepayApiException ('잘못된 암호화 문자열 '); 이 페이지의 코드가없는 것으로 주어진이되어야하는 이유 그러나

static public function decryptAes($strIn, $password) 
{ 
// HEX decoding then AES decryption, CBC blocking with PKCS5 padding. 
// Use initialization vector (IV) set from $str_encryption_password. 
$strInitVector = $password; 

// Remove the first char which is @ to flag this is AES encrypted and HEX decoding. 
$hex = substr($strIn, 1); 

, 내가 해결할 수없는 -

즉 앞의 세그먼트에 문제가 있다는 결론을 내 왼쪽 건드려 져서 이전 버전과 같이 임시로 PHP 5.5.x로 전환 한 다음 5.2.x로 다시 전환해야합니다.

마침내 나는 서버 php 버전을 변경하는 동안 서버가 자동으로 내 사이트 php.in 파일을 사용하지 않도록 설정했다는 것을 알았습니다. (필자는 특정 기본값을 변경하는 것 이외에 많은 것을 모릅니다. 서버가 실행하는 php 버전의 특성). 필자는 php.ini 파일을 복원했지만, 지금까지는 장애인 2.2가 그 위치에서 시작되었습니다.

다른 시도해 볼까요? ZAP, 문제가 해결되었습니다.

그러나 새로운 기본 5.5.9 서버 ini 파일 설정에 암호화 코드와 관련된 최신 문제의 근원이 있는지는 알 수 없습니다. .ini 파일은 default_charset을 2.2.4에서는 iso-8859-1로 설정하고 5.5.9에서는 기본값을 utf-8로 설정합니다.

5.59 ini 파일에서도 default_charset을 iso-8859-1로 설정했으나 £로 표시되도록 고정되었지만? 웹 사이트 콘텐츠에서 SagePay 제출 오류에 아무런 영향을 미치지 않았습니다.

이 심각한 문제 (웹 사이트는 현재 지불을 처리 할 수없는 ..)를 수정하시기 바랍니다.

업데이트 23/10/16 - 문제가 변경되었습니다. 아직 도움이 필요합니다.

Sagepay에 제출하십시오. 그러나 지금은 Sagepay의 응답을 처리 할 수 ​​없기 때문에 도움이 필요합니다. 응답은 SagePay에서 전송되고 응답 파일에서 수신되지만 반환 된 암호화 된 문자열을 처리하는 동안 오류가 발생합니다.

결과적으로 사용자의 브라우저 창이 멈춘 것으로 나타납니다. 이는 비어 있으며 사용자는 내 웹 사이트로 돌아 가지 않습니다. 웹 사이트의 결제 결과 자동 처리 중 하나가 해독 프로세스 오류로 인해 시작되지 않습니다. .

오류는 이미이 질문에 게시 한 코드가 포함 된 functions.php 파일의 줄에서 발생합니다. 라인 (184)에서 발생 된 에러는되어 치명적인 오류 직전

// Throw exception if string is malformed 
if (!preg_match('/^[0-9a-fA-F]+$/', $hex)) 
{ 
throw new SagepayApiException('Invalid encryption string'); 
} 
$strIn = pack('H*', $hex); 

다음 세그먼트

throw new SagepayApiException('Invalid encryption string'); 

:

PHP Fatal error: Class 'SagepayApiException' not found in /web/sites/user/3/84/42307/public/www/My_folder/protx/functions.php on line 184 

라인 (184)은 행 아래 웹 서버 로그에 다음 줄이 있습니다.

PHP Notice: Undefined variable: crypt in /web/sites/user/3/84/42307/public/www/myfolder/protx/completed.php on line 30 

completed.php는 Sagepay 응답이 전달되는 return url의 파일이며 functions.php 파일이 포함되어 있습니다.

는 파일 completed.php 파일

라인 (30)은 다음 (Sageway가 다시 작동 그래도 난 내가 거기 얻고 있었다 제출 내가 가진 나는이 작업을했습니다

$Decoded = DHclassInFunc::decryptAes($crypt,$EncryptionPassword); 

주말과 마지막 밤 이후 적어도 웹 사이트는 다시 지불을 할 수 있습니다).

덧붙여서, 그 측면에서의 수정의 열쇠는, 암호화 파일의 앞에있는 파일의 함수 htmlspecialchars의 인스턴스를 대체하고있어, 이제는 PHP 5.5에 필요한 새로운 구문을 사용하고있는 것처럼 보입니다.아래의 예에서와 같이 문자 집합을 포함 할 수있다 9 :

htmlspecialchars($rs->Fields($kartProps['Korders']['orders']['email']), ENT_COMPAT,'ISO-8859-1', true); 

또한 I가있는 로컬 character_set에 설정 통해 ISO-8859-1 php.ini 파일의 기본 UTF-8 인코딩을 변경. ini 파일.

Sagepay 응답 파일의 암호 해독 중에 일종의 character_set 충돌이 여전히 발생하고 preg_match 함수가 실패하게됩니다.

나는 꽤 많은 일들을 해결하는 능력으로 몸살을 앓 았고 나는 어떤 제안도 크게 감사 할 것입니다.

은 Sagepay를에서 보낸 응답의 URL의 내용에서 데이터를 수신하지 않았기 때문에 해독 스크립트가 작동되지 않은

를 해결했다.

이 응답은 'completed.php'파일에서 수신되어야하며 응답 문자열은 암호 해독 코드가 포함 된 'functions.php'에 전달됩니다.

completed.php에서 PHP 5.2.4에서 작동하는 데 사용되는 URL의 내용을 추출한 다음 줄 파일 : A를

$Decoded = DHclassInFunc::decryptAes(($_GET['crypt']),$EncryptionPassword);// HURRAH ! finally the scripts get the url contents so now works in php 5.5.9. 

아마 초등학교 : 나는이 변경

$Decoded = DHclassInFunc::decryptAes($crypt,$EncryptionPassword); this worked in 5.5.3 but not 5.5.59 

을 유능한 PHP 코더; 적어도 나는 거기에 도착했다.

+0

'Class'SagepayApiException 'not found'예외 문제는 항상 존재하지만 업그레이드 전에 만난 적이 없습니까? '$ hex' (또는'$ strIn') 값이 무엇인지 알 수 있습니까? 그것은 당신에게 단서를 줄 수 있습니다. –

+0

안녕하세요 @ benholness, 나는 $ hex와 $ strIn의 값을 반향하려고하는데 초점을 맞추었고 두 경우 모두 빈 값을 화면에 출력합니다. 내가 에코를 제대로하고 있는지 테스트하기 위해서 나는 에코 바로 앞의 $ hex에 대한 의사 문자열 값을 선언하고 pseudo 값을 정확하게 출력했다. 그런데 이전 테스트에서 sagepay에서 실패한 응답의 URL에서 복사 된 실제 암호화 문자열을 사용하여 $ hex 값을 선언했으며 preg_match가이를 허용했습니다. 그래서 나는 문자열이 비어 있음을 이제 알 수있을 때 pre_match가 실패한다는 것이 거의 놀랍지 않다고 생각합니다. – David

+0

기능 테스트.PHP 스크립트 나는 $ strIn (Sagepay의 반환을 암호 해독하는 코드 섹션에만 존재 함)가 코드의 빈 값이라는 것을 확신합니다. sagepay의 반환 URL에는 암호화 문자열이 포함되어 있습니다 - 왜 그것이 functions.php 스크립트에 도달하지 못했는지에 대한 제안. 이것은 PHP 5.5.9로 변경된 이후입니다. – David

답변

0

은 Sagepay를에서 보낸 응답의 URL의 내용에서 데이터를 수신하지 않았기 때문에 해독 스크립트가 작동되지 않은

를 해결했다.

이 응답은 'completed.php'파일에서 수신되어야하며 응답 문자열은 암호 해독 코드가 포함 된 'functions.php'에 전달됩니다.

completed.php에서 PHP 5.2.4에서 작동하는 데 사용되는 URL의 내용을 추출한 다음 줄 파일 : A를

$Decoded = DHclassInFunc::decryptAes(($_GET['crypt']),$EncryptionPassword);// HURRAH ! finally the scripts get the url contents so now works in php 5.5.9. 

아마 초등학교 : 나는이 변경

$Decoded = DHclassInFunc::decryptAes($crypt,$EncryptionPassword); this worked in 5.5.3 but not 5.5.59 

을 유능한 PHP 코더; 적어도 나는 거기에 도착했다.