在c#中生成一个128位字符串

本文关键字:一个 128位 字符串 | 更新日期: 2023-09-27 18:13:40

我正在用c#开发一个加密用户和管理密码的类项目。我用TripleDESCryptoServiceProvider来加密。

在配置应用中,用户输入用于加密和解密密码的密钥。我想有一个按钮来生成一个密钥来帮助用户,但我在如何随机生成128位的损失。如何生成一个128位的密钥?

在c#中生成一个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.CryptographyAes抽象类,但这是为了更大的上下文,而不仅仅是创建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。