Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从一个种子生成一个加密强随机字节序列?_C#_Random_Cryptography_Prng - Fatal编程技术网

C# 如何从一个种子生成一个加密强随机字节序列?

C# 如何从一个种子生成一个加密强随机字节序列?,c#,random,cryptography,prng,C#,Random,Cryptography,Prng,如何从种子值生成加密强随机字节序列(以便可以再次从同一种子重新生成序列)?有没有好的CSPRNG算法可以用C#实现(最好有好的文档) 另外,or类将满足我的要求,因为Random在加密方面不强,RNGCryptoServiceProvider不允许您设置种子值。非常适合此工作,通常它用作密码哈希函数,但是,您可以从它请求任意多的字节,它将始终返回给定种子的相同字节序列(密码、salt和迭代计数的组合) 以下是MSDN中的示例,其中显示了Rfc2898DeriveBytes的两个实例,它们都返回相

如何从种子值生成加密强随机字节序列(以便可以再次从同一种子重新生成序列)?有没有好的CSPRNG算法可以用C#实现(最好有好的文档)

另外,or类将满足我的要求,因为
Random
在加密方面不强,
RNGCryptoServiceProvider
不允许您设置种子值。

非常适合此工作,通常它用作密码哈希函数,但是,您可以从它请求任意多的字节,它将始终返回给定种子的相同字节序列(密码、salt和迭代计数的组合)

以下是MSDN中的示例,其中显示了
Rfc2898DeriveBytes
的两个实例,它们都返回相同的序列(使用第一个序列对数据块进行对称加密,并使用第二个序列对其进行解密)

使用系统;
使用System.IO;
使用系统文本;
使用System.Security.Cryptography;
公共类RFC2898测试
{
//生成密码为pwd1和salt salt1的密钥k1。
//生成密码为pwd1和salt salt1的密钥k2。
//使用对称加密使用密钥k1加密数据1,创建edata1。
//使用对称解密使用密钥k2解密edata1,创建数据2。
//数据2应该等于数据1。
private const string usageText=“用法:RFC2898\n必须指定加密密码。\n”;
公共静态void Main(字符串[]passwordargs)
{
//如果未指定文件名,请写入用法文本。
if(passwordargs.Length==0)
{
控制台写入线(usageText);
}
其他的
{
字符串pwd1=passwordargs[0];
//创建一个字节数组来保存随机值。
字节[]salt1=新字节[8];
使用(RNGCryptoServiceProvider rngCsp=new RNGCryptoServiceProvider())
{
//用随机值填充数组。
rngCsp.GetBytes(salt1);
}
//数据1可以是字符串或文件内容。
string data1=“一些测试数据”;
//默认迭代计数为1000,因此这两个方法使用相同的迭代计数。
int=1000;
尝试
{
Rfc2898DeriveBytes k1=新的Rfc2898DeriveBytes(pwd1,salt1,myIterations);
Rfc2898DeriveBytes k2=新的Rfc2898DeriveBytes(pwd1,salt1);
//加密数据。
TripleDES encAlg=TripleDES.Create();
encAlg.Key=k1.GetBytes(16);
MemoryStream encryptionStream=新的MemoryStream();
CryptoStream encrypt=新加密流(encryptionStream,encAlg.CreateEncryptor(),CryptoStreamMode.Write);
byte[]utfD1=新系统.Text.UTF8Encoding(false).GetBytes(data1);
加密.Write(utfD1,0,utfD1.Length);
encrypt.FlushFinalBlock();
encrypt.Close();
字节[]edata1=encryptionStream.ToArray();
k1.Reset();
//尝试解密,从而显示它可能是往返的。
TripleDES贴花=TripleDES.Create();
贴花键=k2.GetBytes(16);
贴花IV=包装IV;
MemoryStream DecryptionStreamBack=新建MemoryStream();
CryptoStream DecryptoStream=新加密流(DecryptionStreamBack,贴花.createDecryptoctor(),CryptoStreamMode.Write);
解密.写入(edata1,0,edata1.Length);
decrypt.Flush();
decrypt.Close();
k2.Reset();
string data2=新的UTF8Encoding(false).GetString(DecryptionStreamBack.ToArray());
如果(!data1.Equals(data2))
{
WriteLine(“错误:两个值不相等。”);
}
其他的
{
WriteLine(“两个值相等”);
WriteLine(“k1迭代:{0}”,k1.IterationCount);
WriteLine(“k2迭代:{0}”,k2.IterationCount);
}
}
捕获(例外e)
{
Console.WriteLine(“错误:”,e);
}
}
}
}

假设它是用于测试的,为什么不使用只返回已知数字序列的特殊实现呢?(否则可重复序列的“加密强度”有多大?)@AlexeiLevenkov,因为我需要根据种子生成不同的序列。如果
Random
类的加密能力很强,那么它就可以了。加密安全的随机生成器意味着数字无法预测。此外,数字(或字节)-生成器是。当迭代次数=1时,它非常慢,而当迭代次数为1000次时,它的速度非常慢。如果您在大量迭代的情况下从PBKDF2中消耗了超过20个字节,那么您可能做错了什么。
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

public class rfc2898test
{
    // Generate a key k1 with password pwd1 and salt salt1. 
    // Generate a key k2 with password pwd1 and salt salt1. 
    // Encrypt data1 with key k1 using symmetric encryption, creating edata1. 
    // Decrypt edata1 with key k2 using symmetric decryption, creating data2. 
    // data2 should equal data1. 

    private const string usageText = "Usage: RFC2898 <password>\nYou must specify the password for encryption.\n";
    public static void Main(string[] passwordargs)
    {
        //If no file name is specified, write usage text. 
        if (passwordargs.Length == 0)
        {
            Console.WriteLine(usageText);
        }
        else
        {
            string pwd1 = passwordargs[0];
            // Create a byte array to hold the random value.  
            byte[] salt1 = new byte[8];
            using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
            {
                // Fill the array with a random value.
                rngCsp.GetBytes(salt1);
            }

            //data1 can be a string or contents of a file. 
            string data1 = "Some test data";
            //The default iteration count is 1000 so the two methods use the same iteration count.
            int myIterations = 1000;
            try
            {
                Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(pwd1, salt1, myIterations);
                Rfc2898DeriveBytes k2 = new Rfc2898DeriveBytes(pwd1, salt1);
                // Encrypt the data.
                TripleDES encAlg = TripleDES.Create();
                encAlg.Key = k1.GetBytes(16);
                MemoryStream encryptionStream = new MemoryStream();
                CryptoStream encrypt = new CryptoStream(encryptionStream, encAlg.CreateEncryptor(), CryptoStreamMode.Write);
                byte[] utfD1 = new System.Text.UTF8Encoding(false).GetBytes(data1);

                encrypt.Write(utfD1, 0, utfD1.Length);
                encrypt.FlushFinalBlock();
                encrypt.Close();
                byte[] edata1 = encryptionStream.ToArray();
                k1.Reset();

                // Try to decrypt, thus showing it can be round-tripped.
                TripleDES decAlg = TripleDES.Create();
                decAlg.Key = k2.GetBytes(16);
                decAlg.IV = encAlg.IV;
                MemoryStream decryptionStreamBacking = new MemoryStream();
                CryptoStream decrypt = new CryptoStream(decryptionStreamBacking, decAlg.CreateDecryptor(), CryptoStreamMode.Write);
                decrypt.Write(edata1, 0, edata1.Length);
                decrypt.Flush();
                decrypt.Close();
                k2.Reset();
                string data2 = new UTF8Encoding(false).GetString(decryptionStreamBacking.ToArray());

                if (!data1.Equals(data2))
                {
                    Console.WriteLine("Error: The two values are not equal.");
                }
                else
                {
                    Console.WriteLine("The two values are equal.");
                    Console.WriteLine("k1 iterations: {0}", k1.IterationCount);
                    Console.WriteLine("k2 iterations: {0}", k2.IterationCount);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: ", e);
            }

        }
    }
}