Closed gaufung closed 1 year ago
数据加密是现在计算机网络的基础,通过加密可以确保我们数据的安全性,那么在 C#
中如何使用这些加密算法呢?
Hash 加密是一种单向加密,也就是说将一个输入转换到一个特定空间的数据。通常不能进行反向操作,通过这种方法可以判断输入的内容事否一致。通常有三种类别
该算法已经被标记为不安全算法。
var strStreamOne = new MemoryStream(Encoding.UTF8.GetBytes("This is my password! Dont read me!"));
byte[] hashOne;
using (var hasher = MD5.Create())
{
hashOne = await hasher.ComputeHashAsync(strStreamOne);
}
var hashAsString = Convert.ToHexString(hashOne);
Console.WriteLine("Hash Value:\n" + hashAsString)
通常有 Sha-1
, sha2
这样的算法
var strStreamOne = new MemoryStream(Encoding.UTF8.GetBytes("This is my password! Dont read me!"));
byte[] hashOne;
using (var sha256 = SHA256.Create())
{
hashOne = await sha256.ComputeHashAsync(strStreamOne);
}
var hashAsString = Convert.ToHexString(hashOne);
这是一个需要密钥才能生成的哈希算法
var strStreamOne = new MemoryStream(Encoding.UTF8.GetBytes("This is my password! Dont read me!"));
byte[] hashOne;
byte[] key = Encoding.UTF8.GetBytes("superSecretH4shKey1!");
using (var hmac = new HMACSHA256(key))
{
hashOne = await hmac.ComputeHashAsync(strStreamOne);
}
var hashAsString = Convert.ToHexString(hashOne);
这是一个可以进行加密和解密的算法,两端使用相同的密钥进行工作,通常使用 AES
算法
var dataStr = "This is corporate research! Dont read me!";
var data = Encoding.UTF8.GetBytes(dataStr);
var key = GenerateAESKey();
var encryptedData = Encrypt(data, key, out var iv);
var encryptedDataAsString = Convert.ToHexString(encryptedData);
public static byte[] Encrypt(byte[] data, byte[] key, out byte[] iv)
{
using (var aes = Aes.Create())
{
aes.Mode = CipherMode.CBC; // better security
aes.Key = key;
aes.GenerateIV(); // IV = Initialization Vector
using (var encryptor = aes.CreateEncryptor())
{
iv = aes.IV;
return encryptor.TransformFinalBlock(data, 0, data.Length);
}
}
}
public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
using (var aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC; // same as for encryption
using (var decryptor = aes.CreateDecryptor())
{
return decryptor.TransformFinalBlock(data, 0, data.Length);
}
}
}
public static byte[] GenerateAESKey()
{
var rnd = new RNGCryptoServiceProvider();
var b = new byte[16];
rnd.GetNonZeroBytes(b);
return b;
}
就是加密方和解密方使用不同的密钥来操作,通常分为公钥和私钥,公钥可以公开,任何人都可以加密。但是只有私钥才能解开,反之亦然,私钥加密的内容,只有公钥才能解开。这样可以保证私钥的安全性。最著名的就是 RSA
算法,这也是 HTTPS
协议的基石。
var dataStr = "This is corporate research! Dont read me!";
var data = Encoding.UTF8.GetBytes(dataStr);
var keyLength = 2048; // size in bits
GenerateKeys(keyLength , out var publicKey, out var privateKey);
var encryptedData = Encrypt(data, publicKey);
var encryptedDataAsString = Convert.ToHexString(encryptedData);
public void GenerateKeys(int keyLength, out RSAParameters publicKey, out RSAParameters privateKey)
{
using (var rsa = RSA.Create())
{
rsa.KeySize = keyLength;
publicKey = rsa.ExportParameters(includePrivateParameters: false);
privateKey = rsa.ExportParameters(includePrivateParameters: true);
}
}
public byte[] Encrypt(byte[] data, RSAParameters publicKey)
{
using (var rsa = RSA.Create())
{
rsa.ImportParameters(publicKey);
var result = rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
return result;
}
}
public byte[] Decrypt(byte[] data, RSAParameters privateKey)
{
using (var rsa = RSA.Create())
{
rsa.ImportParameters(privateKey);
return rsa.Decrypt(data, RSAEncryptionPadding.OaepSHA256);
}
}
另外一种是 DSA
算法,用来进行数字签名,因为它只需要校验事否匹配,性能上有优势。
var dsa = DSA.Create();
var dataStr = "This is corporate research! Dont read me!";
var data = Encoding.UTF8.GetBytes(dataStr);
var signedData = Sign(dsa, data);
dsa.Dispose();
public byte[] Sign(DSA dsa, byte[] data)
{
if(dsa is null)
throw new NullReferenceException(nameof(dsa));
var result = dsa.SignData(data, HashAlgorithmName.SHA256);
return result;
}
public bool VerifySignature(DSA dsa, byte[] data, byte[] signedData)
{
if (dsa is null)
throw new NullReferenceException(nameof(dsa));
return dsa.VerifyData(data, signedData, HashAlgorithmName.SHA256);
}
https://code-maze.com/dotnet-cryptography-implementations/