.NET中自动生成的加密密钥

时间:2015-02-20 22:43:23

标签: .net cryptography

可以使用Rijndael或RC2,为关键参数提供空值:

        var r = new RijndaelManaged();
        var encryptor = r.CreateEncryptor(null, null);

主题中的算法将生成随机密钥(firstsecond)。这与msdn有点矛盾,says密钥或iv不应为null。 (可能它在过去以这种方式工作,并且密钥生成稍后添加)。

使用这种随机密钥的理由是什么?显然,只要生成的密钥在创建的加密器中不可用,我们就会产生一些不可恢复的乱码,因此我们无法解密它。

测试用例代码:

        var r = new RijndaelManaged();

        // encryptor 1
        var encryptor = r.CreateEncryptor(null, null);

        var inp = new byte[encryptor.InputBlockSize];
        for (byte i = 0; i < inp.Length; i++)
        {
            inp[i] = i;
        }
        var outp = new byte[encryptor.OutputBlockSize];

        // transform 1
        encryptor.TransformBlock(inp, 0, inp.Length, outp, 0);

        // encryptor 2, same parameters
        var encryptor2 = r.CreateEncryptor(null, null);
        var outp2 = new byte[encryptor.OutputBlockSize];

        // transform 2
        encryptor2.TransformBlock(inp, 0, inp.Length, outp2, 0);

        Assert.AreNotEqual(outp, outp2);

1 个答案:

答案 0 :(得分:2)

我通常使用它创建一个随机密钥来创建一个新密钥的事实,但是然后保存我在加密时使用的密钥,这样我就可以解密了。

您可以做的一件事是生成一个随机密钥来加密某些数据,然后使用RSA公钥加密随机密钥,并将加密的对称密钥与数据一起存储。然后你只需要密钥来解密数据。优点是对称加密比公钥/私钥更快。您使用RSA密钥加密少量数据,并使用较大数据对称。

修改
如果您只是稍微更改一下代码并使用无参数CreateEncryptor

,则可以捕获密钥
var rand = new Random();
var r = new RijndaelManaged();

// Store the key and IV (you need both to decrypt)
var key = r.Key;
var iv = r.IV;

// This will create the encryptor using the key and IV above
var enc = r.CreateEncryptor();

var inp = new byte[enc.InputBlockSize];
rand.NextBytes(inp);

var outp = new byte[enc.OutputBlockSize];

enc.TransformBlock(inp, 0, inp.Length, outp, 0);

// To ensure that we have new keys, create a new Rijndael object
var r2 = new RijndaelManaged();
var enc2 = r2.CreateEncryptor(key, iv);

// Another option would be to set the key and IV of r2 and call the
// parameterless CreateEncryptor
var r3 = new RijndaelManaged();
r3.Key = key;
r3.IV = iv;
var enc3 = r3.CreateEncryptor();

var outp2 = new byte[enc2.OutputBlockSize];
var outp3 = new byte[enc3.OutputBlockSize];
enc2.TransformBlock(inp, 0, inp.Length, outp2, 0);
enc3.TransformBlock(inp, 0, inp.Length, outp3, 0);

if (outp.SequenceEqual(outp2) && outp.SequenceEqual(outp3))
{
    Console.WriteLine("Equal");
    Console.WriteLine("Key: " + Convert.ToBase64String(key));
    Console.WriteLine("IV: " + Convert.ToBase64String(iv));
}

enc.Dispose();
enc2.Dispose();
enc3.Dispose();
r.Dispose();
r2.Dispose();
r3.Dispose();