为什么TripleDES.Create().Key的大小对此算法无效

本文关键字:算法 无效 Create TripleDES Key 为什么 | 更新日期: 2023-09-27 18:21:32

在一种情况下,我需要用不同的密钥解密文本我还需要在代码隐藏中生成有效的密钥。

我用这行生成一个密钥。

var key = Encoding.UTF8.GetString(TripleDES.Create().Key);

但在此方法中不能使用该键。它说"指定的密钥不是这个算法的有效大小"

我该如何解决这种情况?

public class CryptoHelper
{
    public string Encrypt(string toEncrypt, string key)
    {
        var toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);
        var keyArray = Encoding.UTF8.GetBytes(key);
        var tdes = new TripleDESCryptoServiceProvider { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };
        var cTransform = tdes.CreateEncryptor();
        var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        tdes.Clear();
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }
    public string Decrypt(string cipherString, string key)
    {
        var toEncryptArray = Convert.FromBase64String(cipherString.Replace(' ', '+'));
        var keyArray = Encoding.UTF8.GetBytes(key);
        var tdes = new TripleDESCryptoServiceProvider { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };
        var cTransform = tdes.CreateDecryptor();
        var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        tdes.Clear();
        return Encoding.UTF8.GetString(resultArray);
    }
}

为什么TripleDES.Create().Key的大小对此算法无效

如果你写了一个小测试,你的问题就会变得很明显,

var failures = ParallelEnumerable.Range(0, 10000).Count(i =>
    {
        var keyBefore = TripleDES.Create().Key;
        var keyAfter = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(keyBefore));
        return !keyBefore.SequenceEqual(keyAfter);
    });

在我的测试中,每次尝试往返都失败了。这证实了达米恩的评论。

无法保证为密钥生成的字节可以安全round被当作一个有效的UTF-8字符串序列

keyAfter(几乎)总是有些扩展,有时长度加倍。事实上,我不能侥幸得到一把可以往返的钥匙,这可能与避免弱钥匙有关。


但是,如果我尝试

var failures = ParallelEnumerable.Range(0, 10000).Count(i =>
    {
        var keyBefore = TripleDES.Create().Key;
        var keyAfter = Convert.FromBase64String(Convert.ToBase64String(keyBefore));
        return !keyBefore.SequenceEqual(keyAfter);
    });

failures总是等于0。因此,有一个简单的解决方案。