Mcrypt를 OpenSSL로 대체하십시오.
PHPMcrypt를 OpenSSL로 대체하십시오.
현재 우리는 우리의 PHP 응용 프로그램에서 합리적인 데이터를 암호화하기 위해 시스템에 mcrypt 함축적 인 암시를 가지고 있습니다. 이제는 crypt 모듈을 openssl로 변경해야한다는 새로운 요구 사항이 생겼습니다. 중요한 또 다른 사실은 우리가 암호 복어와 모드 ecb를 사용하고 있다는 것입니다. 그래서 나는 차이점이 무엇인지, 그리고 openssl을 사용하여 mcrypt 암호화 된 문자열을 어떻게 해독 할 수 있는지 테스트하기 시작했습니다.
나는 표준 PHP 함수를 사용했다 :
두 가지 방법 모두 다른 결과를 제공합니다. 둘째로 주어진 암호문 (복어)과 두 종류의 모드 (ecb)에서 IV 길이가 필요합니다 (openssl = 0 및 mcrypt = 56).
누구든지 큰 마이그레이션 작업없이 쉽게 모듈을 변경할 수있는 방법을 알고 있습니까?
미리 감사드립니다!
최신 정보:
다음은 테스트 한 코드입니다.
<?php
function say($message){
if(!is_string($message)){
if(!isset($_SERVER["HTTP_USER_AGENT"])) echo "<pre>";
echo var_export($message, true) . ((!isset($_SERVER["HTTP_USER_AGENT"]) ? "\n" : "<br />"));
if(!isset($_SERVER["HTTP_USER_AGENT"])) echo "</pre>";
}else{
echo $message . ((!isset($_SERVER["HTTP_USER_AGENT"]) ? "\n" : "<br />"));
}
}
say("= Begin raw encryption");
$key = "anotherpass";
$str = "does it work";
say(" Params:");
say(" - String to encrypt '".$str."'");
say(" - Key: ".$key);
say("");
$params = array(
"openssl" => array(
"cipher" => "BF",
"mode" => "ECB",
),
"mcrypt" => array(
"cipher" => "blowfish",
"mode" => "ecb",
),
);
say("= Mcrypt");
$handler = mcrypt_module_open($params['mcrypt']['cipher'], '', $params['mcrypt']['mode'], '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($handler), MCRYPT_RAND);
$keysize = mcrypt_enc_get_key_size($handler);
mcrypt_generic_init($handler,$key,"\0\0\0\0\0\0\0\0");
say(" Params:");
say(" - InitVector ".bin2hex($iv)." (bin2hex)");
say(" - Max keysize ".$keysize);
say(" - Cipher ".$params['mcrypt']['cipher']);
say(" - Mode ".$params['mcrypt']['mode']);
say("");
say(" Encryption:");
$m_encrypted = mcrypt_generic($handler, $str);
$m_decrypted = mdecrypt_generic($handler, $m_encrypted);
say(" - Encrypted ".bin2hex($m_encrypted)." (bin2hex)");
say(" - Descrypted ".$m_decrypted);
say("");
say("= Openssl");
say(" Params:");
say(" - InitVector not needed");
say(" - Max keysize ".openssl_cipher_iv_length($params['openssl']['cipher']."-".$params['openssl']['mode']));
say(" - Cipher ".$params['openssl']['cipher']);
say(" - Mode ".$params['openssl']['mode']);
say("");
say(" Encryption:");
$o_encrypted = openssl_encrypt($str,$params['openssl']['cipher']."-".$params['openssl']['mode'],$key,true);
$o_decrypted = openssl_decrypt($o_encrypted,$params['openssl']['cipher']."-".$params['openssl']['mode'],$key,true);
say(" - Encrypted ".bin2hex($o_encrypted)." (bin2hex)");
say(" - Descrypted ".$o_decrypted);
그리고 이것은 내 결과입니다.
= Begin raw encryption
Params:
- String to encrypt 'does it work'
- Key: anotherpass
= Mcrypt
Params:
- InitVector 06a184909d7bf863 (bin2hex)
- Max keysize 56
- Cipher blowfish
- Mode ecb
Encryption:
- Encrypted 0e93dce9a6a88e343fe5f90d1307684c (bin2hex)
- Descrypted does it work
= Openssl
Params:
- InitVector not needed
- Max keysize 0
- Cipher BF
- Mode ECB
Encryption:
- Encrypted 213460aade8f9c14d8d51947b8231439 (bin2hex)
- Descrypted does it work
어쩌면 어떤 아이디어일까요?
감사!
해결법
-
==============================
1.블로우 피시는 블록 암호입니다. 암호화되기 전에 데이터를 채워야합니다. OpenSSL은 PKCS # 7을 사용하고 mcrypt는 PKCS # 5를 사용합니다. 데이터에 대한 다른 패딩 algorythms. 최소 PKCS # 5 패딩 길이는 0이며, PKCS # 7의 경우 1 (위키피디아)입니다. 이 예제를 살펴 보겠습니다 (PKCS # 7 스타일의 mcrypt_encrypt ()에 대한 입력 데이터를 수동으로 채웠습니다).
블로우 피시는 블록 암호입니다. 암호화되기 전에 데이터를 채워야합니다. OpenSSL은 PKCS # 7을 사용하고 mcrypt는 PKCS # 5를 사용합니다. 데이터에 대한 다른 패딩 algorythms. 최소 PKCS # 5 패딩 길이는 0이며, PKCS # 7의 경우 1 (위키피디아)입니다. 이 예제를 살펴 보겠습니다 (PKCS # 7 스타일의 mcrypt_encrypt ()에 대한 입력 데이터를 수동으로 채웠습니다).
<?php $key = "anotherpassword1"; $str = "does it work 12"; $enc = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $str."\1", MCRYPT_MODE_ECB); $dec = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $enc, MCRYPT_MODE_ECB); echo(bin2hex($enc).PHP_EOL); var_dump($dec); $enc = openssl_encrypt($str, 'bf-ecb', $key, true); $dec = openssl_decrypt($enc, 'bf-ecb', $key, true); echo(bin2hex($enc).PHP_EOL); var_dump($dec); ?>
mcrypt_encrypt ()가 호출되기 전에 PKCS # 7을 사용하여 수동 데이터가 채워지 지 않으면 mcrypt_encrypt ()로 암호화 된 openssl_decrypt () 데이터를 사용할 수 없습니다.
귀하의 경우에는 단 하나의 방법이 있습니다 - 데이터를 암호화하십시오.
추신 : 귀하의 소스에 오류가 있습니다 - ECB 모드는 전혀 IV를 사용하지 않습니다 (위키 백과)
-
==============================
2.키가 짧으면 mcrypt의 복어를 마이그레이션 할 때 openssl의 키를 순환시켜야합니다.
키가 짧으면 mcrypt의 복어를 마이그레이션 할 때 openssl의 키를 순환시켜야합니다.
function make_openssl_blowfish_key($key) { if("$key" === '') return $key; $len = (16+2) * 4; while(strlen($key) < $len) { $key .= $key; } $key = substr($key, 0, $len); return $key; }
참조 : https://bugs.php.net/bug.php?id=72362
참고 : Blowfish & ECB를 사용하여 mcrypt에서 OpenSSL로 이동
-
==============================
3.OpenSSL로 암호화하고 mcrypt로 해독 할 때 mcrypt로 암호화 한 것과 같은 결과를 얻으려면 openssl_encrypt로 암호화하기 전에 수동으로 입력 문자열을 널 패드해야하고 OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING 옵션.
OpenSSL로 암호화하고 mcrypt로 해독 할 때 mcrypt로 암호화 한 것과 같은 결과를 얻으려면 openssl_encrypt로 암호화하기 전에 수동으로 입력 문자열을 널 패드해야하고 OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING 옵션.
$str = 'encrypt me'; $cipher = 'AES-256-CBC'; $key = '01234567890123456789012345678901'; $opts = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; $iv_len = 16; $str_len = mb_strlen($str, '8bit'); $pad_len = $iv_len - ($str_len % $iv_len); $str .= str_repeat(chr(0), $pad_len); $iv = openssl_random_pseudo_bytes($iv_len); $encrypted = openssl_encrypt($str, $cipher, $key, $opts, $iv);
mcrypt_decrypt로 해독하면 마치 암호화를 위해 mcrypt를 사용한 것처럼 작동합니다.
mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted, MCRYPT_MODE_CBC, $iv)
-
==============================
4.Blowfish의 기본 패딩은 mcrypt와 Openssl 사이에서 다르지만 수행 할 수없는 것은 잘못되었습니다. 해독에 OPENSSL_ZERO_PADDING 옵션을 사용하면 실제로 두 가지가 호환됩니다.
Blowfish의 기본 패딩은 mcrypt와 Openssl 사이에서 다르지만 수행 할 수없는 것은 잘못되었습니다. 해독에 OPENSSL_ZERO_PADDING 옵션을 사용하면 실제로 두 가지가 호환됩니다.
openssl_decrypt($data, 'bf-ecb', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
from https://stackoverflow.com/questions/9993909/replace-mcrypt-with-openssl by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
JavaScript 변수를 PHP 변수로 사용하려면 어떻게해야합니까? [복제] (0) | 2018.09.18 |
---|---|
mysql 데이터베이스에서 내 BLOB 이미지를 표시하려면 PHP 페이지가 필요합니다. (0) | 2018.09.18 |
속성 [title]이 (가)이 컬렉션 인스턴스에 없습니다. (0) | 2018.09.18 |
PHP 메일 ()을 통해 보낸 메일이 스팸 메일을 보내지 않도록하려면 어떻게합니까? (0) | 2018.09.18 |
정의되지 않은 오프셋 PHP 오류 (0) | 2018.09.18 |