C# 如何为加密算法创建加密密钥?
我想使用.Net安全命名空间中可用的加密算法,但我试图了解如何生成密钥,例如AES算法需要256位、16字节的密钥和一些初始化向量,也就是几个字节C# 如何为加密算法创建加密密钥?,c#,.net,security,encryption,C#,.net,Security,Encryption,我想使用.Net安全命名空间中可用的加密算法,但我试图了解如何生成密钥,例如AES算法需要256位、16字节的密钥和一些初始化向量,也就是几个字节 我可以在Key和IV中使用任意值的组合吗?e、 g.键和IV中的所有零是否有效?我知道算法的细节,它执行大量的异或运算,所以零不会有任何好处,但是这些算法有任何限制吗 或者我必须使用某种程序生成密钥并将其永久保存在某个地方吗 我想在加密后将数据存储在数据库中,安全配置文件数据(如用户名、密码、电话号码等)和密钥将仅对连接字符串中提到的数据库用户和管理
我想在加密后将数据存储在数据库中,安全配置文件数据(如用户名、密码、电话号码等)和密钥将仅对连接字符串中提到的数据库用户和管理员可用。生成特定长度的随机字母/十六进制代码 此函数(取自)返回特定长度的随机键:
private static string CreateSalt(int size)
{
//Generate a cryptographic random number.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);
// Return a Base64 string representation of the random number.
return Convert.ToBase64String(buff);
}
这真的取决于你打算用钥匙做什么 如果密钥是由计算机生成的(并且可以是任意随机值),我通常使用两个guid的SHA256。这大约是你在没有硬件随机数生成器的情况下得到的随机数
您可以对所有0使用密钥,但显然它不会非常安全 如果您使用加密来交换数据,那么您将需要密钥交换协议,但您自己并不制作密钥交换协议,而是使用现成的协议,如TLS或SSL 如果您使用加密来存储数据,那么您可以使用(或其.net等价物)生成IV,并将其保存在文档中(很明显,不需要保护IV)。您从不写下密钥,密钥由用户提供。通常使用或其.Net等效项从密码短语派生密钥 更新 要在数据库中存储仅对用户和管理员可用的机密,您需要使用3个密钥:
- 一个用来加密数据的密钥(称为DK密钥)
- 一个用于加密DK密钥的用户密钥(称为UK)
- 一个管理员密钥加密DK密钥(称为AK)
作为提示,了解什么是IV或如何使用C#中的AES,以及密码算法如何工作,将使您在解决此类问题时获得0(零)的牵引力。问题永远不是使用什么IV和密钥,问题始终是密钥配置。对于实际的加密操作,只需使用数据库的内置支持,请参阅。我可以很容易地说,您需要的唯一功能是TDE(),以防止意外丢失介质。使用
系统、安全、加密、随机数生成器来生成随机字节:
var rnd = new System.Security.Cryptography.RandomNumberGenerator.Create();
var key = new byte[50];
rnd.GetBytes(key);
你真的应该用正确的方法:)
1) 使用安全生成的随机IV
2) 使用安全生成的随机密钥
3) 不要使用ECB模式-永远
上面的代码将正确、安全地为您生成随机IV和随机密钥。听起来您需要读入Rfc2898DeriveBytes类
Rfc2898DeriveBytes.GetBytes();
它有一个方法(如上所述),允许您通过输入一个int值来定制输入对称加密算法的.Key和.IV属性的字节数组的大小。MS官方的70-536手册建议按语法将KeySize属性/8分开
即三倍或三倍。无论您使用什么,算法本身都会有一些需要先满足的预需求。即满足关键尺寸条件。运行时将自动为您填充属性和字段等最佳和最强的值。但是静脉注射和钥匙需要来自你。这说明了如何执行以下操作:
RijndaelManaged myAlg = new RiRijndaelManaged();
byte[] salt = Encoding.ASCII.GetBytes("Some salt value");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes("some password", salt);
myAlg.Key = key.GetBytes( myAlg.KeySize / 8);
myAlg.IV = key.GetBytes( myAlg.BlockSize / 8);
// myAld should now fully set-up.
在上面,你可以看到我所说的按语法做的意思,因为这应该是非常正确的
这一切都是为了你,你甚至不必为满足它的预先要求而眨眼
Microsoft 70-536手册指出,.Key属性需要您提供的字节数组
以字节(而不是位)的形式向它们发送数据。RFC类以字节为单位工作,而KeySize属性以位为单位工作。1字节=8位。你能看到这是怎么回事吗?
这应该会让你了解为什么上面的代码示例是这样做的!我研究过它,它对我来说非常有意义
上面的答案应该允许您使用提供的密码和静态salt值创建算法对象,该静态salt值可以是两端的硬代码。您需要做的唯一一件事就是担心如何确保存储在.Key和.IV中的字节数组安全地传输到收件人,以便能够成功解密您加密的消息。通过安全地重建相同的算法对象
OBTW:
AESManaged有一个keysize请求:128位=16字节!!!
(8*8=64,每字节64位/8位=8字节)因此
64*2=128位,8*2,==>16字节密钥大小
256Bit=32字节
根据70-536官方培训工具包,Aes的密钥大小仅限于128位。例如,256位、192位和128位密钥大小可用于Rijndael类
另一方面,你可以完全忘记那些废话,只需使用.GenerateKey和GenerateIV方法,就可以省去整理预先共享和约定的通行证的所有麻烦
RijndaelManaged myAlg = new RiRijndaelManaged();
byte[] salt = Encoding.ASCII.GetBytes("Some salt value");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes("some password", salt);
myAlg.Key = key.GetBytes( myAlg.KeySize / 8);
myAlg.IV = key.GetBytes( myAlg.BlockSize / 8);
// myAld should now fully set-up.