为什么TripleDES.Create()。Key不是此算法的有效大小?

在我需要使用不同密钥解密文本的情况下,我还需要在后面的代码中生成有效密钥。

我正在使用此行生成密钥。

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); } } 

如果你写一点测试,你的问题就变得很明显,

 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); }); 

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

无法保证为密钥生成的字节可以安全地往返到字符串中,就好像它们是有效的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 。 所以,有一个简单的解决方案。