Why the TripleDES.Create().Key is not a valid size

2019-06-07 00:59发布

问题:

in a case i need to decrypt texts with diffrent keys i also need to genreate valid keys in code behind.

i am using this line to generate a key.

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

but can't use that key in this method. it says "Specified key is not a valid size for this algorithm"

how can i fix this situation?

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

回答1:

If you write a little test, your problem becomes obvious,

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

In my testing, every attempted roundtrip fails. This confirms Damien's comment.

There's no guarantee that the bytes generated for a key can be safely round-tripped into a string by acting as if they're a valid UTF-8 sequence.

The keyAfter is (almost) always somewhat expanded, sometimes doubled in length. In fact, I'm unable to fluke a key that is round trippable, this may have something to do with avoiding weak keys.


However, if i try

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 always equals 0, as expected. So, there is a simple solution.



标签: c# tripledes