m使用
public function encrypt($plain_str,$key)
{
$str= mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plain_str, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND));
$str = urlencode(base64_encode($str));
return $str ;
}
public function decrypt($cipher_str,$key)
{
$str = urldecode(base64_decode($cipher_str));
return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND));
}
关于加密:201433~58~g@fds.com~20140820142427
我得到:%2BAihYMLwpwrsmL4lSGGzwFTfonvdCyOb%2BCGEUJ%2F%2BE%2F7ZnvgwFRYFtlazQeSrVjUjyaaGZADK8%2BZyynIGxyt4VQ%3D%3D
解密:%2BAihYMLwpwrsmL4lSGGzwFTfonvdCyOb%2BCGEUJ%2F%2BE%2F7ZnvgwFRYFtlazQeSrVjUjyaaGZADK8%2BZyynIGxyt4VQ%3D%3D
我得到:201433~58~g@fds.com~20140820142427
但是
当字符串格式错误时,删除某些字符
像这样:%2BAihYMLwpwrsmL4lSGGzwFTfonvdCyOb%2BCGEUJ%2F%2BE%2F7Z
解密我得到:201433~58~g@fds.com~201408201424O#¿W«Gݽˋ¯ È#'oP´ŸØw\Â⦑
我怎样才能发现这种异常?
答案 0 :(得分:0)
首先,我想在您的代码中列出一些缺陷:
MCRYPT_RIJNDAEL_128
进行加密,但是您获得MCRYPT_RIJNDAEL_256
的IV大小。 (顺便说一句,在ECB模式下忽略IV,这是不使用它的原因之一)MCRYPT_RAND
作为随机源,这是不安全的。您应该使用MCRYPT_DEV_URANDOM
(也就是new default in PHP 5.6)。urlencode()
生成的密文,Base64编码是网址安全的。现在,回答你的问题......这是通过HMAC完成的。使用HMAC的最简单方法是在其前面加上密文(你也应该用IV做;不要担心,这不是秘密):
public function encrypt($plainText, $encKey, $hmacKey)
{
$ivSize = mcrypt_get_iv_size('rijndael-128', 'ctr');
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
$cipherText = mcrypt_encrypt('rijndael-128', $encKey, $plainText, 'ctr', $iv);
$cipherText = $iv.$cipherText;
$hmac = hash_hmac('sha256', $cipherText, $hmacKey, true);
return base64_encode($hmac.$cipherText);
}
public function decrypt($cipherText, $encKey, $hmacKey)
{
$cipherText = base64_decode($cipherText);
if (strlen($cipherText) <= 32)
{
throw new Exception('Authentication failed!');
}
$recvHmac = substr($cipherText, 0, 32);
$cipherText = substr($cipherText, 32);
$calcHmac = hash_hmac('sha256', $cipherText, $hmacKey, true);
if ( ! hash_equals($recvHmac, $calcHmac))
{
throw new Exception('Authentication failed!');
}
$ivSize = mcrypt_get_iv_size('rijndael-128', 'ctr');
$iv = substr($cipherText, $ivSize);
$cipherText = substr($cipherText, $ivSize);
return mcrypt_decrypt('rijndael-128', $encKey, $cipherText, 'ctr', $iv);
}
请注意,加密密钥和HMAC密钥不同 - 它们大多数是相同的密钥。另外,对于Rijndael-128,你应该创建一个128位(或16字节)的随机密钥,这不是你可以用键盘输入的东西。以下是如何生成一个:
$encKey = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);