PHP7.1에서 mcrypt를 대체하기 위해 openssl을 사용하는 방법 소개

不言
풀어 주다: 2023-04-02 08:50:01
원래의
1857명이 탐색했습니다.

이 글에서는 주로 PHP7.1에서 mcrypt를 대체하기 위해 openssl을 사용한 상세한 예시를 소개하고 있습니다. 필요하신 분들은 참고하시면 됩니다.

PHP 개발 시 mcrypt 관련 기능을 이용하면 AES 암호화를 쉽게 수행할 수 있습니다. 및 암호 해독 작업을 수행하지만 mcrypt 확장은 PHP7.1에서 폐기되므로 다른 구현을 찾아야 합니다. mcrypt를 openssl로 바꾸는 것은 이미 마이그레이션 매뉴얼에서 지적되었지만 구체적인 예는 제공되지 않습니다. 대부분의 시나리오를 대체할 수 있는 많은 예가 온라인에 있지만 자세한 내용은 설명되지 않습니다. 마찬가지로, 단순히 온라인 예제를 사용하면 특정 코드 시나리오에서 코드 교체 전후에 호환성 문제가 발생할 수 있습니다. 아래에서 구체적인 코드와 이유에 대해 이야기해 보겠습니다.

먼저 대체 코드를 직접 제공한 후, 코드에서 문제를 분석합니다. (이 글에서 분석된 알고리즘은 AES-128-CBC입니다.)

교체 예시

이 예시에서는 주로 패딩이 다르기 때문에 mcrypt를 사용하는 두 가지 방법을 보여줍니다(패딩에 대해서는 아래에서 설명합니다). 전체 암호화 및 암호 해독 과정에서 더 완전한 코드는 자동으로 채우기 및 채우기 제거를 구현하고 간단한 코드는 채우기를 직접 무시하지만 두 방법 모두 실제 개발(7.1 이전 버전)에서는 정상적으로 실행될 수 있으므로 권장됩니다. 패딩을 추가합니다. 다음 구체적인 예를 참조하십시오.

mcrypt는 패딩을 사용하지 않습니다.

mcrypt 암호화:

 $key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; 
 $iv = 'aaaaaaaaaaaaaaaa';
 $data = 'dataString';
 $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
 mcrypt_generic_init($cipher, $key, $iv);
 $cipherText256 = mcrypt_generic($cipher, $data);
 mcrypt_generic_deinit($cipher);
 return bin2hex($cipherText256);
로그인 후 복사

동일한 기능에 대한 openssl 암호화 코드:

 $key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; 
 $iv = 'aaaaaaaaaaaaaaaa';
 $data = 'dataString';
로그인 후 복사

 $data = $data . str_repeat("\x00", 16 - (strlen($data) % 16)); // 双引号可以解析asc-ii码\x00
 return bin2hex(openssl_encrypt($data, "AES-256-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv));
로그인 후 복사

엠크립트 패딩 사용

mcrypt 암호화:

$key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; 
 $iv = 'aaaaaaaaaaaaaaaa';
 $data = 'dataString';
 // 填充(移除填充反着移除即可)
 $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
 $pad = $block - (strlen($data) % $block);
 if ($pad <= $block) {
 $char = chr($pad);
 $data .= str_repeat($char, $pad);
 }
 $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($cipher, $key, $iv);
 $cipherText256 = mcrypt_generic($cipher, $data);
 mcrypt_generic_deinit($cipher);
 return bin2hex($cipherText256);
로그인 후 복사

동일한 기능에 대한 openssl 암호화 코드:

 $key = &#39;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#39;; 
 $iv = &#39;aaaaaaaaaaaaaaaa&#39;;
 $data = &#39;dataString&#39;;  
return bin2hex(openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv));
로그인 후 복사

위 예제는 모두 성공적으로 실행됩니다. 첫 번째 예제에서는 패딩을 사용하지 않고 패딩을 사용합니다. openssl ) 및 두 번째 예(패딩 포함, openssl에서는 패딩이 사용되지 않음)는 교체 전후에 동일한 출력을 가지며 호환성 문제가 없습니다. 코드의 다양한 채우기 방법에 따라 다양한 교체 솔루션을 선택할 수 있지만 세 가지 세부 사항을 설명해야 합니다

왜 채우기가 있나요?

openssl로 대체한 후 알고리즘 이름이 다른 이유는 무엇인가요?
다음 장에서는 채우기 및 알고리즘을 자세히 분석합니다.

Padding

패딩이 있는 이유는 암호화 알고리즘에서 시작됩니다. AES-128-CBC 알고리즘에서는 암호화할 문자열이 길이가 16바이트마다 세그먼트로 분할되고 단계별로 계산되므로 16바이트 미만의 세그먼트가 채워지기 때문입니다. 따라서 두 가지 유형의 예제가 제공됩니다. 하나는 기본 채우기를 사용하는 것이고 다른 하나는 독립적 채우기를 사용하는 것입니다. openssl로 대체할 때 패딩 구성표를 선택하려면 mcrypt 및 openssl의 기본 및 자율 패딩에 대한 이해가 필요합니다.

mcrypt는 기본적으로 채워져 있습니다

php의 소스코드를 보면 기본적으로 x00으로 채워져 있는 것을 볼 수 있는데, 실제로는 x00으로 채워져 있지 않다는 것을 알 수 있습니다. String에는 16비트 널 문자가 먼저 적용되므로 초기화 중에는 각 바이트가 x00이 됩니다. 실제로는 패딩이 없다고 할 수 있지만 기본 패딩을 사용하여 얻은 암호화된 문자열은 16비트입니다. 다음 형식:

mcrypt 기본 패딩

따라서 해독할 때 추가 x00을 제거해야 합니다. 물론 게으르고 x00을 제거하지 않을 수도 있습니다. PHP에서는 문자열 "stringx00"과 문자열 "string"이 길이가 다르다는 점을 제외하면 동일한 성능을 가지므로 차이가 없는 것 같습니다. 다음 코드는

 // 尾部包含若干个`\x00` 均可功输出true
 if ("string\x00" == "string") { // 用双引号可解析\x00
 echo true;
 }
로그인 후 복사

x00으로 채워진 예입니다. 문자열 길이에 주의를 기울이면 x00을 사용한 패딩이 길이에 영향을 미치는 것을 볼 수 있습니다.)

mcrypt 자율 패딩

패딩 알고리즘은 다음 알고리즘에 따라 수행되어야 합니다.

패딩 추가

/**
 * 填充算法
 * @param string $source
 * @return string
 */
 function addPKCS7Padding($source)
 {
 $source = trim($source);
 $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);

 $pad = $block - (strlen($source) % $block);
 if ($pad <= $block) {
  $char = chr($pad);
  $source .= str_repeat($char, $pad);
 }
 return $source;
 }
로그인 후 복사

패딩을 추가한 후 문자열은 실제로 다음과 같습니다.

패딩 제거

 /**
 * 移去填充算法
 * @param string $source
 * @return string
 */
 function stripPKSC7Padding($source)
 {
 $source = trim($source);
 $char = substr($source, -1);
 $num = ord($char);
 if ($num == 62) return $source;
 $source = substr($source, 0, -$num);
 return $source;
 }
로그인 후 복사

openssl 기본 패딩

기본 방법은 다음과 일치합니다. 표준 mcrypt의 자율 패딩 방식이므로 두 번째 예에서는 위 패딩 알고리즘을 사용한 후 호환성 문제 없이 openssl_encrypt로 직접 대체할 수 있습니다. 패딩된 암호화 문자열은 다음과 같은 형식을 갖습니다.

패딩 및 패딩 제거 기능은 openssl_encrypt 및 openssl_decrypt에 내장되어 있으므로 패딩을 독립적으로 구현할 필요가 없으면 직접 사용할 수 있습니다. 패딩을 고려해야 합니다

openssl 자율 채우기

openssl_encrypt는 자율 채우기를 지원하는 옵션 매개 변수를 제공하지만 PHP 소스 코드에서 openssl 테스트 사례 코드를 참조한 후 올바른 사용법을 찾았습니다.

 // if we want to manage our own padding
 $padded_data = $data . str_repeat(&#39; &#39;, 16 - (strlen($data) % 16));
 $encrypted = openssl_encrypt($padded_data, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
 $output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
 var_dump(rtrim($output));
(备注:如上,OPENSSL_ZERO_PADDING 并非是为0填充的意思)
로그인 후 복사

이것으로 첫 번째 예에서 openssl_encrypt 이전에 x00을 충전하는 독립 포인트 코드가 추가된 이유를 설명할 수 있습니다.

위의 암호화와 복호화에서 채우기 논리가 다릅니다. 위의 예는 잘 설명할 수 있습니다:

예 1:

mcrypt는 암호화할 때 패딩을 사용하지 않기 때문에 x00으로 패딩되므로 openssl로 교체할 때 x00 채우기를 독립적으로 구현해야 합니다.

예 2:

mcrypt는 암호화 시 표준 패딩을 사용하는데, openssl의 패딩 방식도 표준 패딩이므로 직접 사용할 수 있습니다.

이를 분석해 보면 패딩 전략이 무엇이든 암호화 시에는 패딩 추가에 주의가 필요하고, 복호화 시에는 패딩을 제거해야 한다는 사실을 알 수 있습니다. 이제 위 예제의 채우기 관련 분석이 완료되었습니다. 다음으로 대체 알고리즘을 선택하는 방법을 살펴보겠습니다.

알고리즘 선택

위의 예에서는 mcrypt에서 AES가 실행되는 문제가 있습니다- 128- CBC 알고리즘, openssl에서 어떻게 AES_256으로 대체할 수 있나요?
이 점에 대해서는 한동안 소스코드를 확인해봐도 이유를 찾지 못했는데(능력 제한~) 다음을 통해 알아냈습니다. 정보, 기능이 아직 완료되었습니다

openssl 암호 해독 mcrypt AES 데이터 비호환 문제

mcrypt_generic을 openssl_encrypt로 변환 질문하기

#🎜 🎜# 이유를 찾는 학생이 있다면 메시지를 남겨주시면 감사하겠습니다.

Summary

암호화에 mcrypt AES를 사용하는 부분에 대해, 암호화 과정에서 문제가 있는 경우 교체 프로세스에서는 알고리즘 교체 또는 채우기라는 두 가지 측면을 고려할 수 있습니다. 동시에 충족해야 할 조건 중 하나는 다양한 충전 방법에 따라 선택하는 것입니다. 교체 시 고려해야 할 가장 중요한 것은 교체 후 변경 사항이 발생하지 않는지 확인하는 것입니다. 약간의 차이(마지막 몇 개의 문자열의 차이)만 있지만 여러 플랫폼에서 동시에 수정하는 것은 번거롭지만 변경 사항이 적을수록 위험은 줄어듭니다.

이 기사에서는 AES 알고리즘에 대해 간략하게 설명할 뿐입니다. 다른 알고리즘이 적용 가능한지는 아직 연구되지 않았습니다.

위 내용은 모두의 학습에 도움이 되기를 바랍니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요!

관련 권장사항:

PHP는 캔버스 이미지를 HTML5로 서버에 저장하는 것을 구현합니다

# 🎜🎜#다중 상속을 달성하기 위한 PHP 인터페이스 다중 상속 및 tarits 메소드 effect_php Skill


Laravel 프레임워크 + Blob으로 구현된 다중 이미지 업로드 기능 분석 예


위 내용은 PHP7.1에서 mcrypt를 대체하기 위해 openssl을 사용하는 방법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿