PHP7.1에서 mcrypt를 대체하기 위해 openssl을 사용하는 방법 소개
이 글에서는 주로 PHP7.1에서 mcrypt를 대체하기 위해 openssl을 사용하는 방법을 소개합니다. 이제 특정 참고 가치가 있으므로 필요한 친구들이 참고할 수 있습니다.
openssl을 사용하여 PHP7에서 mcrypt를 대체하세요. 1
PHP 개발에서는 mcrypt 관련 기능을 사용하여 AES 암호화 및 복호화 작업을 쉽게 수행할 수 있습니다. 그러나 PHP7.1에서는 mcrypt 확장이 지원되지 않으므로 다른 구현을 찾아야 합니다. mcrypt를 openssl로 바꾸는 것은 이미 마이그레이션 매뉴얼에서 지적되었지만 구체적인 예는 제공되지 않습니다. 대부분의 시나리오를 대체할 수 있는 많은 예가 온라인에 있지만 자세한 내용은 설명되지 않습니다. 마찬가지로, 단순히 온라인 예제를 사용하면 특정 코드 시나리오에서 코드 교체 전후에 호환성 문제가 발생할 수 있습니다. 아래에서 구체적인 코드와 이유에 대해 이야기해 보겠습니다.
먼저 대체 코드를 직접 제공한 후, 코드에서 문제를 분석합니다. (이 글에서 분석한 알고리즘은 AES-128-CBC입니다.)
대체 예시
이 예시에서는 주로 padding의 차이로 인해 mcrypt를 사용하는 두 가지 방법을 보여줍니다. (padding에 대해서는 아래에서 설명하겠습니다.) . 전체 암호화 및 암호 해독 과정에서 더 완전한 코드는 자동으로 채우기 및 채우기 제거를 구현하고 간단한 코드는 채우기를 직접 무시하지만 두 방법 모두 실제 개발(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 with padding
엠크립트 암호화 :
$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, '', 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'; 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<으로 채워져 있지 않습니다. /code>에서 16비트 빈 문자열이 먼저 적용되는 것을 소스코드에서 확인할 수 있으므로 실제로는 초기화 시 각 바이트가 <code>x00
라고 할 수 있습니다. 패딩은 없지만 원래x00
이므로 기본 패딩을 사용하여 얻은 암호화된 문자열은 다음 형식을 따릅니다.x00
进行填充,事实上,并非是以x00
进行填充,从源码中可以发现,首先申请了一个16位的空字符串,所以初始化时每位字节均为x00
, 实际上可以说其中并没有填充,只是它本来就是x00
,使用默认填充得到的加密字符串会是如下形式:所以解密时则要移除多余的
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
따라서 해독할 때 추가x00
를 제거해야 합니다. 물론 게으른 상태에서x00
을 제거하지 않을 수도 있습니다. 왜냐하면 php에서는 "stringx00"이라는 문자열과 "string"이라는 문자열이 길이가 다른 것 외에는 성능이 같기 때문에 차이가 없는 것 같습니다. 다음 코드는// if we want to manage our own padding $padded_data = $data . str_repeat(' ', 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));
로그인 후 복사로그인 후 복사- 🎜mcrypt의 독립 패딩 🎜🎜패딩 알고리즘은 다음 알고리즘에 따라 수행되어야 합니다. 🎜🎜
- 🎜🎜Add padding🎜rrreee🎜padding을 추가한 후 문자열은 실제로 다음과 같습니다.
🎜🎜🎜🎜패딩 제거🎜rrreee🎜🎜🎜🎜openssl 기본 패딩🎜🎜기본 방법은 표준 mcrypt 자율 패딩 방법과 일치하므로 두 번째 예에서는 위의 패딩 알고리즘을 사용한 후 호환성 문제 없이 openssl_encrypt로 직접 대체할 수 있습니다. 패딩된 암호화 문자열은 다음 형식입니다. 🎜🎜
🎜🎜🎜패딩 및 패딩 제거 기능은 openssl_encrypt
및openssl_decrypt
에 내장되어 있으므로 패딩을 독립적으로 구현해야 하는 경우가 아니면 직접 사용할 수 있습니다. , 고려할 필요가 없습니다. Filling🎜🎜🎜🎜🎜openssl 자율 채우기🎜openssl_encrypt提供了option参数以支持自主填充,但在查阅php源码中openssl的测试用例代码才找到正确用法:
// if we want to manage our own padding $padded_data = $data . str_repeat(' ', 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
的代码原因了
x00
입니다. 예: (문자열 길이에 주의하세요. x00
로 패딩하면 길이에 영향을 미치는 것을 볼 수 있습니다.)
从以上的加、解密针对填充逻辑不同,针对上文中的示例可以很好地解释:
示例1:
mcrypt加密时未使用填充,故以\x00
进行了填充,所以在替换成openssl,需要自主实现\x00
填充。示例2:
mcrypt加密时使用了标准的填充,同时openssl的填充方式也为PHP7.1에서 mcrypt를 대체하기 위해 openssl을 사용하는 방법 소개,故直接使用即可。
分析到这,可以发现,无论是何种填充策略都需注意在加密时加入填充,在解密时则必须要移除填充。至此,上文中示例中的填充相关则分析完成了,接下来我们再看看如何选择替换后的算法。
选择算法
在以上的示例中,有一个问题在于,mcrypt中的AES-128-CBC算法,在openssl中怎么替换成了AES_256?
关于这一点, 我也未找到合理的解释,查看源码一时半会也没找到原因(能力有限~),但通过以下资料,还是完成了功能
openssl 解密 mcrypt AES 数据不兼容问题
Convert mcrypt_generic to openssl_encrypt Ask Question
若是有同学找到原因,欢迎给我留言,谢谢。
总结
对于使用mcrypt AES 进行加密密的部分,若是在替换过程中问题, 可以从算法替换或填充这两方面着手考虑下。同时还是一必须满足的条件是根据不同的填充方式选择, 替换最重要的就要考虑兼容问题,保证替换后不发生任何改变。 虽然只是只是有细微的差别----尾部几个字符串的不同,但若是在多平台中同时进行修改也是一件麻烦事,但变动越少风险越小。
本文只是针对AES算法进行了简单说明,对于其他算法是否适用还有待研究。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
위 내용은 PHP7.1에서 mcrypt를 대체하기 위해 openssl을 사용하는 방법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Alipay PHP ...

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

PHP 개발에서 견고한 원칙의 적용에는 다음이 포함됩니다. 1. 단일 책임 원칙 (SRP) : 각 클래스는 하나의 기능 만 담당합니다. 2. Open and Close Principle (OCP) : 변경은 수정보다는 확장을 통해 달성됩니다. 3. Lisch의 대체 원칙 (LSP) : 서브 클래스는 프로그램 정확도에 영향을 미치지 않고 기본 클래스를 대체 할 수 있습니다. 4. 인터페이스 격리 원리 (ISP) : 의존성 및 사용되지 않은 방법을 피하기 위해 세밀한 인터페이스를 사용하십시오. 5. 의존성 반전 원리 (DIP) : 높고 낮은 수준의 모듈은 추상화에 의존하며 종속성 주입을 통해 구현됩니다.

시스템이 다시 시작된 후 UnixSocket의 권한을 자동으로 설정하는 방법. 시스템이 다시 시작될 때마다 UnixSocket의 권한을 수정하려면 다음 명령을 실행해야합니다.

기사는 PHP 5.3에 도입 된 PHP의 LSB (Late STATIC BING)에 대해 논의하여 정적 방법의 런타임 해상도가보다 유연한 상속을 요구할 수있게한다. LSB의 실제 응용 프로그램 및 잠재적 성능

phpstorm에서 CLI 모드를 디버그하는 방법은 무엇입니까? PHPStorm으로 개발할 때 때때로 CLI (Command Line Interface) 모드에서 PHP를 디버그해야합니다 ...

PHP 개발에서 PHP의 CURL 라이브러리를 사용하여 JSON 데이터를 보내면 종종 외부 API와 상호 작용해야합니다. 일반적인 방법 중 하나는 컬 라이브러리를 사용하여 게시물을 보내는 것입니다 ...

기사는 입력 유효성 검사, 인증 및 정기 업데이트를 포함한 취약점을 방지하기 위해 프레임 워크의 필수 보안 기능을 논의합니다.
