>  기사  >  백엔드 개발  >  PHP에서 Mcrypt 암호화 및 암호 해독 대신 OpenSSL을 사용하는 방법은 무엇입니까?

PHP에서 Mcrypt 암호화 및 암호 해독 대신 OpenSSL을 사용하는 방법은 무엇입니까?

php中世界最好的语言
php中世界最好的语言원래의
2017-12-20 14:37:191717검색

최근 WeChat 공개 계정을 개발할 때 문제를 발견했습니다. 즉, PHP7.1이 mcrypt에서 더 이상 사용되지 않으므로 이 문제를 해결할 수 있는 방법만 찾았습니다. 오늘은 이 문제를 어떻게 해결했는지 알려드리겠습니다. 솔루션 아이디어.

php7.1 출시 이후 새로운 기능은 많은 PHP 사용자들의 관심을 끌었고, 모두가 새로운 기능이 가져오는 이점과 편의성에 대해 논의했습니다. 그러나 php7.0에서 php7.1로 업그레이드하면 과거에 일반적으로 사용되던 확장(mcrypt 확장)이 폐기(obsolete)됩니다. 해당 관계자는 해당 해결방안을 제시하지만, 더 자세한 해결방안은 제시하지 않습니다. 그래서 여기에 함정이 있습니다:

오늘 WeChat 개방형 플랫폼을 사용하여 콘텐츠 관리 시스템에 연결할 때 공식 계정을 바인딩할 때 계속 실패했습니다.

이유:

디버깅 중에 직접적인 이유는 다음과 같은 것임을 발견했습니다. 오픈 플랫폼 인증 이벤트 작성(이 인증 이벤트는 티켓을 업데이트하기 위해 10분마다 이벤트를 전송합니다), 즉:


여기에 URL이 채워져 있고 디버깅을 통해 이 URL이 올바른 것으로 확인되었으며 WeChat도 10분마다 푸시하는데 끝까지 티켓을 못받았네요. 코드를 보니 위챗에서 데이터를 복호화할 때 오류가 보고되었기 때문인 것으로 나타났습니다.

<?php
  
function aes_decode($message, $encodingaeskey = &#39;&#39;, $appid = &#39;&#39;) {
 $key = base64_decode($encodingaeskey . &#39;=&#39;);
  
 $ciphertext_dec = base64_decode($message);
 $iv = substr($key, 0, 16);
  
 $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($module, $key, $iv);
 $decrypted = mdecrypt_generic($module, $ciphertext_dec);
 mcrypt_generic_deinit($module);
 mcrypt_module_close($module);
  
 $pad = ord(substr($decrypted, -1));
 if ($pad < 1 || $pad > 32) {
 $pad = 0;
 }


그곳이 바로 그 곳입니다. 내 환경이 PHP 7.1이므로 정보를 검색한 결과 PHP 7.1이 Mcrypt를 포기했기 때문에 이 코드의 mcrypt_*를 실행할 수 없습니다.

해결책:

정보를 찾아보니 Mcrypt가 OpenSSL로 대체될 수 있다는 사실이 밝혀졌습니다(OpenSSL 확장이 설치되어 있지만 일반적으로 기본적으로 설치되어 있는 경우).

openssl은 많은 비밀번호 알고리즘과 실용적인 비밀번호를 통합한 강력한 툴킷입니다. 도구. 파일을 암호화하고 해독하기 위해 키와 인증서를 생성하기 위해 제공되는 명령 콘솔 도구를 사용할 수도 있고, 코드에서 전송된 정보를 암호화하기 위해 제공하는 API 인터페이스를 사용할 수도 있습니다.

따라서 위의 코드는 다음과 같이 변경될 수 있습니다:

<?php
  
function aes_decode($message, $encodingaeskey = &#39;&#39;, $appid = &#39;&#39;) {
 $key = base64_decode($encodingaeskey . &#39;=&#39;);
  
 $ciphertext_dec = base64_decode($message);
 $iv = substr($key, 0, 16);
  
 /* mcrypt对称解密代码在PHP7.1已经被抛弃了,所以使用下面的openssl来代替
 $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($module, $key, $iv);
 $decrypted = mdecrypt_generic($module, $ciphertext_dec);
 mcrypt_generic_deinit($module);
 mcrypt_module_close($module);
 */
 $decrypted = openssl_decrypt($ciphertext_dec, &#39;AES-256-CBC&#39;, $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
  
 $pad = ord(substr($decrypted, -1));
 if ($pad < 1 || $pad > 32) {
 $pad = 0;
 }


추가:

위의 암호 해독이 수정되었으므로 해당 Mcrypt 암호화도 수정되어야 합니다. 전체 네트워크에 게시되지 않으며 메시지와 같은 이벤트는 푸시될 수 없습니다
암호화된 소스 코드는 다음과 같습니다:

<?php
function aes_encode($message, $encodingaeskey = &#39;&#39;, $appid = &#39;&#39;) {
 $key = base64_decode($encodingaeskey . &#39;=&#39;);
 $text = random(16) . pack("N", strlen($message)) . $message . $appid;
 $iv = substr($key, 0, 16);
  
 $block_size = 32;
 $text_length = strlen($text);
 $amount_to_pad = $block_size - ($text_length % $block_size);
 if ($amount_to_pad == 0) {
 $amount_to_pad = $block_size;
 }
 $pad_chr = chr($amount_to_pad);
 $tmp = &#39;&#39;;
 for ($index = 0; $index < $amount_to_pad; $index++) {
 $tmp .= $pad_chr;
 }
 $text = $text . $tmp;
 $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
 $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($module, $key, $iv);
 $encrypted = mcrypt_generic($module, $text);
 mcrypt_generic_deinit($module);
 mcrypt_module_close($module);
  
 $encrypt_msg = base64_encode($encrypted);
 return $encrypt_msg;
}

수정된 코드는:

<?php
function aes_encode($message, $encodingaeskey = &#39;&#39;, $appid = &#39;&#39;) {
 $key = base64_decode($encodingaeskey . &#39;=&#39;);
 $text = random(16) . pack("N", strlen($message)) . $message . $appid;
 $iv = substr($key, 0, 16);
  
 $block_size = 32;
 $text_length = strlen($text);
 $amount_to_pad = $block_size - ($text_length % $block_size);
 if ($amount_to_pad == 0) {
 $amount_to_pad = $block_size;
 }
 $pad_chr = chr($amount_to_pad);
 $tmp = &#39;&#39;;
 for ($index = 0; $index < $amount_to_pad; $index++) {
 $tmp .= $pad_chr;
 }
 $text = $text . $tmp;
 /* mcrypt对称加密代码在PHP7.1已经被抛弃了,所以使用下面的openssl来代替
 $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
 $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($module, $key, $iv);
 $encrypted = mcrypt_generic($module, $text);
 mcrypt_generic_deinit($module);
 mcrypt_module_close($module);
 */
  
 $encrypted = openssl_encrypt($text, &#39;AES-256-CBC&#39;, $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
 $encrypt_msg = base64_encode($encrypted);
 return $encrypt_msg;
}

특별 참고 사항: WeChat 개발과 관련된 모든 프로세스의 경우 PHP 7.1, 대칭 암호화 및 복호화에 Mcrypt가 사용되는지 확인해야 합니다. WeChat 개발 문서에 사용된 데모도 암호화 및 복호화에 Mcrypt를 사용한다는 점에 유의해야 합니다.

요약

예제를 통한 Ajax 비동기 요청 기술 설명

AJAX의 일반적인 구문은 무엇입니까

AJAX 원칙과 CORS 도메인 간 방법

위 내용은 PHP에서 Mcrypt 암호화 및 암호 해독 대신 OpenSSL을 사용하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.