3DES PHP 即使在末尾添加一个字符也能解密相同的结果
3DES PHP decrypts same result even if a char is added at the end
所以我正在使用这个 class 来加密或解密数据:
class CryptData
{
private $hash;
function __construct($hash) {
$key = md5($hash, true);
$key .= substr($key, 0, 8);
$this->hash = $key;
}
public function Encrypt($data)
{
$encData = openssl_encrypt($data, 'DES-EDE3', $this->hash, OPENSSL_RAW_DATA);
return base64_encode($encData);
}
public function Decrypt($data)
{
$data = base64_decode($data);
return openssl_decrypt($data, 'DES-EDE3', $this->hash, OPENSSL_RAW_DATA);
}
}
它工作正常,但是例如,如果我使用:
hash = 12345
text = 1234567891234567
然后加密然后结果
decData = LQ1zff+UiAAs6GXEgA5x6beMPOubhpcA
现在,如果我尝试将此数据解密回纯文本,那么它会给出正确的结果,但即使我在 decData 的末尾添加任何字符,如
decData = LQ1zff+UiAAs6GXEgA5x6beMPOubhpcAa
令人惊讶的是它也给出了正确的纯文本..!!
经过几次测试后我注意到,decData 末尾没有“=”,如果我添加一个字符,那么它将解密为文本而不会出错。
例如,如果我尝试
hash = 12345
text = 12345
那么结果就是
decData = CQm/ZBYSrrs=
现在如果我解密这个在末尾添加一个字符就会出错。
总而言之,当我尝试加密长度为 16 或更长的文本时,解密数据中没有“=”。我对此没有任何问题,但如果我尝试解密在末尾添加任何字符的解密数据,它会返回正确的文本。
为什么会这样,我的数据是否存在与此相关的安全问题?
Base64 用于将二进制数据编码为文本,其中每个 Base64 字符代表 6 位。每 3 个字节(24 位)的输入给出 4 个 Base64 个字符。在输入长度不是 3 的倍数的情况下,Base64 的最后一个块用一个或两个 '='
填充
Base64 编码数据需要在 4 个 Base64 字符块中才有效 Base64.似乎 php 的 base64_decoder(..)
只是忽略了您最后一个无效的 Base64 字符。您可以使用以下代码查看:
echo strlen(base64_decode("LQ1zff+UiAAs6GXEgA5x6beMPOubhpcA"));
echo "\n";
echo strlen(base64_decode("LQ1zff+UiAAs6GXEgA5x6beMPOubhpcAa"));
给予:
24
24
所以我正在使用这个 class 来加密或解密数据:
class CryptData
{
private $hash;
function __construct($hash) {
$key = md5($hash, true);
$key .= substr($key, 0, 8);
$this->hash = $key;
}
public function Encrypt($data)
{
$encData = openssl_encrypt($data, 'DES-EDE3', $this->hash, OPENSSL_RAW_DATA);
return base64_encode($encData);
}
public function Decrypt($data)
{
$data = base64_decode($data);
return openssl_decrypt($data, 'DES-EDE3', $this->hash, OPENSSL_RAW_DATA);
}
}
它工作正常,但是例如,如果我使用:
hash = 12345
text = 1234567891234567
然后加密然后结果
decData = LQ1zff+UiAAs6GXEgA5x6beMPOubhpcA
现在,如果我尝试将此数据解密回纯文本,那么它会给出正确的结果,但即使我在 decData 的末尾添加任何字符,如
decData = LQ1zff+UiAAs6GXEgA5x6beMPOubhpcAa
令人惊讶的是它也给出了正确的纯文本..!! 经过几次测试后我注意到,decData 末尾没有“=”,如果我添加一个字符,那么它将解密为文本而不会出错。 例如,如果我尝试
hash = 12345
text = 12345
那么结果就是
decData = CQm/ZBYSrrs=
现在如果我解密这个在末尾添加一个字符就会出错。
总而言之,当我尝试加密长度为 16 或更长的文本时,解密数据中没有“=”。我对此没有任何问题,但如果我尝试解密在末尾添加任何字符的解密数据,它会返回正确的文本。
为什么会这样,我的数据是否存在与此相关的安全问题?
Base64 用于将二进制数据编码为文本,其中每个 Base64 字符代表 6 位。每 3 个字节(24 位)的输入给出 4 个 Base64 个字符。在输入长度不是 3 的倍数的情况下,Base64 的最后一个块用一个或两个 '='
填充Base64 编码数据需要在 4 个 Base64 字符块中才有效 Base64.似乎 php 的 base64_decoder(..)
只是忽略了您最后一个无效的 Base64 字符。您可以使用以下代码查看:
echo strlen(base64_decode("LQ1zff+UiAAs6GXEgA5x6beMPOubhpcA"));
echo "\n";
echo strlen(base64_decode("LQ1zff+UiAAs6GXEgA5x6beMPOubhpcAa"));
给予:
24
24