PHP 7.2 後 mcrypt 被拿掉了,但是偏偏以前使用的演算法,PHP7.2 的 OpenSSL 不支援,所以要重新來找新的加解密演算法。
PHP 建議與不建議使用的 加解密演算法
加解密演算法這麼多種,要怎麼挑選呢?
PHP 官方文件的範例就有排除法,排掉 (ECB, RC2, RC4, DES, 3DES, MD5 based)後,能用的演算法就剩不多,在從裡面來挑選一下。
PHP: openssl_get_cipher_methods - Manual,下述程式取自此篇:
<?php $ciphers = openssl_get_cipher_methods(); $ciphers_and_aliases = openssl_get_cipher_methods(true); $cipher_aliases = array_diff($ciphers_and_aliases, $ciphers); //ECB mode should be avoided $ciphers = array_filter( $ciphers, function($n) { return stripos($n,"ecb")===FALSE; } ); //At least as early as Aug 2016, Openssl declared the following weak: RC2, RC4, DES, 3DES, MD5 based $ciphers = array_filter( $ciphers, function($c) { return stripos($c,"des")===FALSE; } ); $ciphers = array_filter( $ciphers, function($c) { return stripos($c,"rc2")===FALSE; } ); $ciphers = array_filter( $ciphers, function($c) { return stripos($c,"rc4")===FALSE; } ); $ciphers = array_filter( $ciphers, function($c) { return stripos($c,"md5")===FALSE; } ); $cipher_aliases = array_filter($cipher_aliases,function($c) { return stripos($c,"des")===FALSE; } ); $cipher_aliases = array_filter($cipher_aliases,function($c) { return stripos($c,"rc2")===FALSE; } ); print_r($ciphers); print_r($cipher_aliases); ?>
程式跑出來,能使用的演算法:
Array
(
[18] => AES128
[19] => AES192
[20] => AES256
[21] => BF
[26] => CAST
[27] => CAST-cbc
[50] => IDEA
[82] => aes128
[83] => aes192
[84] => aes256
[85] => bf
[90] => blowfish
[91] => cast
[92] => cast-cbc
[115] => idea
)
這些跑出來的演算法,該挑哪一個呢?在 PHP 上述的官網下面有程式,直接可以測試演算法的速度,程式如下:
<?php const TEST_COUNT = 100000; const SOURCE = 'Note that HTML tags are not allowed in the posts, but the note formatting is preserved.'; const KEY = "password"; function TESTER( $testing_function, $argument ) { $t = microtime(true); for ($test_iterator = 0; $test_iterator < TEST_COUNT; $test_iterator++) { $testing_function( $argument ); } return round(microtime(true) - $t, 4); } $crypt = function($cipher) { $ivlen = openssl_cipher_iv_length($cipher); $iv = openssl_random_pseudo_bytes($ivlen); openssl_encrypt(SOURCE, $cipher, KEY, $options=0, $iv); }; $methods = openssl_get_cipher_methods(false); array_splice( $methods, 0, count($methods) / 2); $timings = array(); foreach ($methods as $cypher) { $time = TESTER( $crypt, $cypher ); $timings[ $cypher ] = $time; echo str_pad($cypher, 40, ' ', STR_PAD_LEFT), " have time ", str_pad($time, 8, STR_PAD_LEFT), ' seconds. ', PHP_EOL; } uasort($timings, function($a, $b){ return $a <=> $b; }); $min_time = round(reset($timings) / TEST_COUNT, 7); $min_cypher = key($timings); $max_time = round(end($timings) / TEST_COUNT, 7); $max_cypher = key($timings); echo '-------------', PHP_EOL; echo "Total tests: ", count($timings), PHP_EOL; echo "Max timing : {$max_time} seconds for `{$max_cypher}` algorithm.", PHP_EOL; echo "Min timing : {$min_time} seconds for `{$min_cypher}` algorithm.", PHP_EOL; echo 'Details: ', PHP_EOL; foreach ($timings as $m => $t) { echo '- ', str_pad($t, 8, STR_PAD_LEFT), " seconds for `{$m}`", PHP_EOL; } echo PHP_EOL; ?>
速度跑完後,應該就可以評估要挑選哪個演算法了~
相關網頁
- Encryption operating modes: ECB vs CBC - 為何不要用 ECB 要用 CBC
- Openssl blowfish cbc (BF-CBC) or AES-256-CBC
- Is AES-256-CBC more secure than BF-CBC? Or is it just another way of encryption?
- both blowfish & AES are block ciphers,AES is said that is more secure than blowfish...