在c#中生成一个128位字符串
本文关键字:一个 128位 字符串 | 更新日期: 2023-09-27 18:13:40
我正在用c#开发一个加密用户和管理密码的类项目。我用TripleDESCryptoServiceProvider
来加密。
在配置应用中,用户输入用于加密和解密密码的密钥。我想有一个按钮来生成一个密钥来帮助用户,但我在如何随机生成128位的损失。如何生成一个128位的密钥?
要生成用于加密的随机值,您应该使用RNGCryptoServiceProvider
:
byte[] bytes = new byte[16];
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(bytes);
要将这个字节序列转换为字符串,您可以使用十六进制(BitConverter.ToString
)或Base64 (Convert.ToBase64String
)。
但是这里有一些奇怪的地方:
- 3DES使用168位密钥
- 如果你想使用对称加密,你应该使用AES。3DES并没有完全被破坏,但它几乎只能用于遗留使用。
- 请注意您选择的分组密码操作模式。您通常需要适当的IV, MAC和安全链接模式 通常你应该对密码进行散列而不是加密。参见如何安全地散列密码?在安全。
我完全理解你想要什么,而不是传递url与http://mydomain.com?Id = 123,需要用加密后的值传递。当有人点击这个带有加密id的url时,你想要解密url的值。
有两个程序:
加密:1 -将"ID"(通常是整数)转换为字符串。var NewId = Convert。ToString ((ID);2 -使用一个短语打乱加密。例如:"我爱巧克力"(如果你有参数数据库的话,这句话可以从你的参数数据库中获取…)
解密:1 -使用相同的阻塞短语来整理。2 -使用Convert将被解密的内容再次转换为整数。ToInt32 (shuffed Variable Above)
你将不得不实现两个函数:
加密功能:
private string Encrypt(string clearText)
{
string EncryptionKey = "I love chocolate";
byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
解密功能:
private string Decrypt(string cipherText)
{
string EncryptionKey = "I love chocolate";
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = System.Text.Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
将ID加密为ID =" 123"时,ID的值为ID =" B8 + iXv5/8BUQEbHt8//fGA =="。
当您解密ID值"B8 + iXv5/8BUQEbHt8//fGA =="时,您将再次获得"123"。
c#中的一个示例:
var OriginalId = 123;
var EncrypetedId = Encrypt(Convert.ToString(OriginalId));
//for recovering original value
var OriginalID = Convert.ToInt32(Decrypt(EncrypetedId));
我希望这对你有帮助
看一下RNGCryptoServiceProvider
类,特别是GetNonZeroBytes
方法。也许,您可以通过base64编码来运行该字节串,以使其可读。
RNGCryptoServiceProvider
已过时:
RNGCryptoServiceProvider已经过时了。要生成随机数,请使用使用RandomNumberGenerator静态方法之一。
这将生成128位和256位密钥:
private void PrintBase64Hex(byte[] bytes)
{
var base64String = Convert.ToBase64String(bytes);
var hexString = Convert.ToHexString(bytes);
Console.WriteLine(base64String);
Console.WriteLine(hexString);
}
[TestMethod]
[DataRow(16)]
[DataRow(32)]
public void GenerateKeyTest(int n)
{
byte[] bytes = new byte[n];
var rng = RandomNumberGenerator.Create();
rng.GetBytes(bytes);
PrintBase64Hex(bytes);
Assert.AreEqual(n, bytes.Length);
}
16字节(128位):
sHG3x5uO2gkx6AkLT5AVSA== B071B7C79B8EDA0931E8090B4F901548
32字节(256位):
VXlFUX/OnJmHk7UWogFZZ494oISoTSm5Kvqz+4EXue4= 557945517FCE9C998793B516A20159678F78A084A84D29B92AFAB3FB8117B9EE
一个"alternative"是使用System.Security.Cryptography
的Aes
抽象类,但这是为了更大的上下文,而不仅仅是创建256位密钥。
[TestMethod]
public void AESTest()
{
var sut = Aes.Create();
PrintBase64Hex(sut.Key);
Assert.AreEqual(32, sut.Key.Length);
}
我补充说AES比三倍DES更强,并且迄今为止AES在cpu中已经加速了很多年,所以没有理由特权它。
即使三重DES也不足以保护
三重DES (3DES) -也称为三重数据加密算法(TDEA)——是一种使用DES加密三次的方法。但即使是三倍DES已被证明对暴力攻击无效(除了大大放慢进程)。
根据NIST于2018年7月19日发布的指南草案,TDEA/3DES正式退役。指导方针建议对于所有新应用程序,不建议使用三重DES,之后也不允许使用2023 .
只用Guid.NewGuid()
。它创建一个RFC 4122 v4(随机)UUID。详情请参见RFC 4122§4.4。