PHP 将 mcrypt 转换为 openssl
PHP Converting mcrypt to openssl
我知道 3DES 和 MD5 不安全。一旦它再次工作,我将努力更换它们,
我有一个移动应用程序使用 3DES 和密钥的 MD5 作为秘密密钥与 PHP 应用程序通信。
现在这段代码在 PHP 5.3 上完美运行(这是我生成的示例)
mcrypt_decrypt(
MCRYPT_3DES,
md5(
utf8_encode(
"MobileAppSecureKey"
),
true
),
base64_decode("bkCfcseIt/TPsgNCdyX9fv2/4MjOJdaPXakNNbxQT3n6tXHa5bDoXojQ3g7jPLCu+wjwD0guQzw3hCFUSVx47PmDNHASk7g/kJ4K4tX0VGI="),
MCRYPT_MODE_CBC,
base64_decode("cTOCJ/iYL18=")
)
现在我已经将它移植过来使用 OpenSSL 方法我的新代码是
openssl_decrypt(
base64_decode("bkCfcseIt/TPsgNCdyX9fv2/4MjOJdaPXakNNbxQT3n6tXHa5bDoXojQ3g7jPLCu+wjwD0guQzw3hCFUSVx47PmDNHASk7g/kJ4K4tX0VGI="),
'DES-EDE3-CBC',
md5(
utf8_encode(
"MobileAppSecureKey"
),
true
),
0,
base64_decode("cTOCJ/iYL18=")
)
但是新代码不起作用,它给出了来自 openssl_error_string()
的错误 error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
我不确定为什么它在 mcrypt
中完美运行时抱怨最终块长度
用于生成测试数据的代码来自移动设备,移动应用程序是 Cordova 应用程序并使用 CryptoJS library
key = CryptoJS.MD5(key);
// copy 3DES subkey 1 to the last 64 bit to make a full 192-bit key
key.words[4] = key.words[0];
key.words[5] = key.words[1];
if(typeof(iv) === "undefined"){
iv = CryptoJS.lib.WordArray.random(8);
}
var encrypted = CryptoJS.TripleDES.encrypt(pt, key, {iv: iv});
return {"str":encrypted.toString(), "iv":CryptoJS.enc.Base64.stringify(iv)};
加密的负载是
{"jsonrpc":"2.0","method":"events.enableParentGenres","params":[159],"id":1}
已尝试修改,
根据yivi建议,选项已设置为OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
根据 Tuckbros 的建议,已填充消息
$message_padded = base64_decode("bkCfcseIt/TPsgNCdyX9fv2/4MjOJdaPXakNNbxQT3n6tXHa5bDoXojQ3g7jPLCu+wjwD0guQzw3hCFUSVx47PmDNHASk7g/kJ4K4tX0VGI=");
$message_padded = str_pad($message_padded,
strlen($message_padded) + 8 - strlen($message_padded) % 8, "[=15=]");
这两个都防止了关于最终块长度的错误,但是当 运行 通过代码时加密的有效载荷没有解密。
您传入的参数openssl_decrypt
似乎有误;您将 OPTIONS
参数作为 0
传递,您必须将其设置为 OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
,因为您为函数提供了原始数据 (base64_decode
)。
密钥还需要转换为 192 位密钥,如 javascript 代码中所示:
$key = md5(utf8_encode("MobileAppSecureKey"), true);
//key.words[4] = key.words[0];
//key.words[5] = key.words[1];
for($i = 0; $i < 8; $i++) {
$key[$i + 16] = $key[$i];
}
试试这个:
$key = md5(utf8_encode("MobileAppSecureKey"), true);
$data = base64_decode("bkCfcseIt/TPsgNCdyX9fv2/4MjOJdaPXakNNbxQT3n6tXHa5bDoXojQ3g7jPLCu+wjwD0guQzw3hCFUSVx47PmDNHASk7g/kJ4K4tX0VGI=");
for($i = 0; $i < 8; $i++) {
$key[$i + 16] = $key[$i];
}
$decoded = openssl_decrypt(
$data,
'DES-EDE3-CBC',
$key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
base64_decode("cTOCJ/iYL18=")
);
echo "$decoded = {$decoded}";
// Will output:
// $decoded = {"jsonrpc":"2.0","method":"events.enableParentGenres","params":[159],"id":1}
我知道 3DES 和 MD5 不安全。一旦它再次工作,我将努力更换它们,
我有一个移动应用程序使用 3DES 和密钥的 MD5 作为秘密密钥与 PHP 应用程序通信。
现在这段代码在 PHP 5.3 上完美运行(这是我生成的示例)
mcrypt_decrypt(
MCRYPT_3DES,
md5(
utf8_encode(
"MobileAppSecureKey"
),
true
),
base64_decode("bkCfcseIt/TPsgNCdyX9fv2/4MjOJdaPXakNNbxQT3n6tXHa5bDoXojQ3g7jPLCu+wjwD0guQzw3hCFUSVx47PmDNHASk7g/kJ4K4tX0VGI="),
MCRYPT_MODE_CBC,
base64_decode("cTOCJ/iYL18=")
)
现在我已经将它移植过来使用 OpenSSL 方法我的新代码是
openssl_decrypt(
base64_decode("bkCfcseIt/TPsgNCdyX9fv2/4MjOJdaPXakNNbxQT3n6tXHa5bDoXojQ3g7jPLCu+wjwD0guQzw3hCFUSVx47PmDNHASk7g/kJ4K4tX0VGI="),
'DES-EDE3-CBC',
md5(
utf8_encode(
"MobileAppSecureKey"
),
true
),
0,
base64_decode("cTOCJ/iYL18=")
)
但是新代码不起作用,它给出了来自 openssl_error_string()
error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
我不确定为什么它在 mcrypt
中完美运行时抱怨最终块长度用于生成测试数据的代码来自移动设备,移动应用程序是 Cordova 应用程序并使用 CryptoJS library
key = CryptoJS.MD5(key);
// copy 3DES subkey 1 to the last 64 bit to make a full 192-bit key
key.words[4] = key.words[0];
key.words[5] = key.words[1];
if(typeof(iv) === "undefined"){
iv = CryptoJS.lib.WordArray.random(8);
}
var encrypted = CryptoJS.TripleDES.encrypt(pt, key, {iv: iv});
return {"str":encrypted.toString(), "iv":CryptoJS.enc.Base64.stringify(iv)};
加密的负载是
{"jsonrpc":"2.0","method":"events.enableParentGenres","params":[159],"id":1}
已尝试修改,
根据yivi建议,选项已设置为OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
根据 Tuckbros 的建议,已填充消息
$message_padded = base64_decode("bkCfcseIt/TPsgNCdyX9fv2/4MjOJdaPXakNNbxQT3n6tXHa5bDoXojQ3g7jPLCu+wjwD0guQzw3hCFUSVx47PmDNHASk7g/kJ4K4tX0VGI=");
$message_padded = str_pad($message_padded,
strlen($message_padded) + 8 - strlen($message_padded) % 8, "[=15=]");
这两个都防止了关于最终块长度的错误,但是当 运行 通过代码时加密的有效载荷没有解密。
您传入的参数openssl_decrypt
似乎有误;您将 OPTIONS
参数作为 0
传递,您必须将其设置为 OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
,因为您为函数提供了原始数据 (base64_decode
)。
密钥还需要转换为 192 位密钥,如 javascript 代码中所示:
$key = md5(utf8_encode("MobileAppSecureKey"), true);
//key.words[4] = key.words[0];
//key.words[5] = key.words[1];
for($i = 0; $i < 8; $i++) {
$key[$i + 16] = $key[$i];
}
试试这个:
$key = md5(utf8_encode("MobileAppSecureKey"), true);
$data = base64_decode("bkCfcseIt/TPsgNCdyX9fv2/4MjOJdaPXakNNbxQT3n6tXHa5bDoXojQ3g7jPLCu+wjwD0guQzw3hCFUSVx47PmDNHASk7g/kJ4K4tX0VGI=");
for($i = 0; $i < 8; $i++) {
$key[$i + 16] = $key[$i];
}
$decoded = openssl_decrypt(
$data,
'DES-EDE3-CBC',
$key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
base64_decode("cTOCJ/iYL18=")
);
echo "$decoded = {$decoded}";
// Will output:
// $decoded = {"jsonrpc":"2.0","method":"events.enableParentGenres","params":[159],"id":1}