Cha*_*son 3 php c# encryption 3des
我正在编写一个用于登录的简单加密系统,但我遇到了一个小问题.C#加密功能:
public static string EncryptString(string Message, string Passphrase)
{
byte[] Results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
// Step 1. We hash the passphrase using MD5
// We use the MD5 hash generator as the result is a 128 bit byte array
// which is a valid length for the TripleDES encoder we use below
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
// Step 2. Create a new TripleDESCryptoServiceProvider object
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
// Step 3. Setup the encoder
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
// Step 4. Convert the input string to a byte[]
byte[] DataToEncrypt = UTF8.GetBytes(Message);
// Step 5. Attempt to encrypt the string
try
{
ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
}
finally
{
// Clear the TripleDes and Hashprovider services of any sensitive information
TDESAlgorithm.Clear();
HashProvider.Clear();
}
// Step 6. Return the encrypted string as a base64 encoded string
return Convert.ToBase64String(Results);
}
Run Code Online (Sandbox Code Playgroud)
EncryptString("test", "123456")
回报"Yjaqhc7RFds="
.
php中的相同代码:
<?php
$key = "123456";
function pkcs7_pad($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
$input = pkcs7_pad("test", 16);
$key = md5(utf8_encode($key), true);
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$encrypted_data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
echo base64_encode($encrypted_data);
?>
Run Code Online (Sandbox Code Playgroud)
回来了"dybhiZYdKG8pNCgCFkbV6g=="
?我究竟做错了什么?
您遇到此问题,因为Triple DES的密钥大小为168位(21字节),但MD5生成的哈希值仅为16字节(128位).
这意味着密钥必须扩展到168位,因此Triple DES可以工作.事实证明,这种从128位到168位的推导在C#中的工作方式与在PHP中的工作方式不同,因此有效使用的密钥不同,导致加密数据不同.
现在您有两个选择:
如果使用支持128位密钥的密码,则可以避免与密钥大小差异相关的所有问题.这需要对代码进行最少的更改.例如,您可以使用Rijndael(AES).
C#:TripleDESCryptoServiceProvider
改为RijndaelManaged
.
其他所有东西都可以保持不变.(演示)
PHP:使用MCRYPT_RIJNDAEL_128
而不是三元组(Demo):
function encrypt_pkcs7($str, $key)
{
$key = md5(utf8_encode($key), true);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
return base64_encode($ciphertext);
}
echo encrypt_pkcs7('test', '123456');
Run Code Online (Sandbox Code Playgroud)
请注意,AES的有效密钥大小大于Triple DES.虽然Triple DES'密钥长168位,但它只提供112位安全性.如果我是你,我会选择这个选项.
如果使用比Triple DES实际使用的更大的密钥,C#和PHP似乎同意如何将其减少到168位.你可以使用像SHA-256这样的哈希函数来做到这一点,它生成一个256位的哈希并将其修剪为192位(24字节):
C#:使用SHA256CryptoServiceProvider
和Array.Copy
获取192位密钥,并将其与程序的其余部分一起使用:( 演示)
SHA256CryptoServiceProvider HashProvider = new SHA256CryptoServiceProvider();
byte[] temp = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
byte[] key = new byte[24];
Array.Copy(temp, key, 24);
Run Code Online (Sandbox Code Playgroud)
PHP:hash()
与SHA-256一起使用并substr()
获取192位密钥
function encrypt_pkcs7($str, $key)
{
// derive 192-bit key using SHA-256
$key = substr(hash('sha256', $key, true), 0, 24);
$block = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_ECB);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $str, MCRYPT_MODE_ECB);
return base64_encode($ciphertext);
}
echo encrypt_pkcs7('test', '123456');
Run Code Online (Sandbox Code Playgroud)
看起来我不能提供168位密钥TripleDESCryptoServiceProvider
,我不知道为什么.
考虑使用SSL; 即使这是一个自签名的证书.它重新发明了轮子,当涉及密码学时这是一项特别危险的任务.
考虑使用ECB以外的操作模式(例如:CBC).使用ECB会增加安全风险.阅读有关分组密码操作模式的维基百科文章.
除非你绝对需要一个明文密码(很少这种情况),你应该哈希你的密码.阅读有关保护密码的文章.
考虑使用适当的基于密码的密钥派生函数,如PBKDF2,而不是像MD5或SHA系列这样的通用哈希函数.这将使关键难度更大.有关更多信息,请阅读上一个要点中的文章.
归档时间: |
|
查看次数: |
4247 次 |
最近记录: |