0


C# 实现对称加密算法(AES)与非对称加密算法(RSA),包含前端加密对应算法实现

C# 实现对称加密算法(AES)与非对称加密算法(RSA),包含前端对应加密算法实现

一、两者的含义

1、对称加密:

一种既简单速度又快的加密方式,加密与解密使用的都是同一个密钥,别名又叫做:单密钥加密;对称加密有很多公开算法,并且因为它效率很高,所以适用于加密大量数据的场合;但其密钥的传输过程是不安全的,并且容易被破解,密钥管理起来也相对麻烦。

2、非对称加密:

需要两个密钥来进行加密和解密,这两个密钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥),如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。加密密钥是公开的,密钥的分配和管理就很简单,而且能够很容易地实现数字签名,因此最适合于电子商务应用的需要;但是如果对大数量进行操作,计算量特别大,速度远远比不上对称加密。

详细请阅读这篇文章 https://blog.csdn.net/qq_38556796/article/details/126706393

二、后端代码实现

1、AES对称加密算法(CBC模式,多一个初始化向量,安全性高)

IV:初始化向量,配合秘钥一起使用,每次加密时随机生成,解密需要秘钥与IV一起才能解密
代码如下:

usingSystem;usingSystem.IO;usingSystem.Security.Cryptography;usingSystem.Text;namespaceAes{publicclassAesHelper{privateconstint KEY_SIZE =256;privateconstint BLOCK_SIZE =128;privateconststring KEY_CHARS ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";privateconststring IV_CHARS ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";publicstaticstringEncrypt(string plainText,string key,string iv){byte[] keyBytes = Encoding.UTF8.GetBytes(key);byte[] ivBytes = Encoding.UTF8.GetBytes(iv);using(Aes aes = Aes.Create()){
                aes.KeySize = KEY_SIZE;
                aes.BlockSize = BLOCK_SIZE;
                aes.Key = keyBytes;
                aes.IV = ivBytes;
                aes.Mode = CipherMode.CBC;ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);using(MemoryStream ms =newMemoryStream()){using(CryptoStream cs =newCryptoStream(ms, encryptor, CryptoStreamMode.Write)){
                        cs.Write(plainBytes,0, plainBytes.Length);}byte[] encryptedBytes = ms.ToArray();return Convert.ToBase64String(encryptedBytes);}}}publicstaticstringDecrypt(string cipherText,string key,string iv){byte[] keyBytes = Encoding.UTF8.GetBytes(key);byte[] ivBytes = Encoding.UTF8.GetBytes(iv);using(Aes aes = Aes.Create()){
                aes.KeySize = KEY_SIZE;
                aes.BlockSize = BLOCK_SIZE;
                aes.Key = keyBytes;
                aes.IV = ivBytes;
                aes.Mode = CipherMode.CBC;ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);byte[] cipherBytes = Convert.FromBase64String(cipherText);using(MemoryStream ms =newMemoryStream()){using(CryptoStream cs =newCryptoStream(ms, decryptor, CryptoStreamMode.Write)){
                        cs.Write(cipherBytes,0, cipherBytes.Length);}byte[] decryptedBytes = ms.ToArray();return Encoding.UTF8.GetString(decryptedBytes);}}}publicstaticstringGenerateKey(){Random random =newRandom();StringBuilder sb =newStringBuilder();for(int i =0; i < KEY_SIZE /8; i++){int index = random.Next(KEY_CHARS.Length);
                sb.Append(KEY_CHARS[index]);}return sb.ToString();}publicstaticstringGenerateIV(){Random random =newRandom();StringBuilder sb =newStringBuilder();for(int i =0; i < BLOCK_SIZE /8; i++){int index = random.Next(IV_CHARS.Length);
                sb.Append(IV_CHARS[index]);}return sb.ToString();}}}

1.1、加解密测试:

string plainText ="Hello World!";string key = AesHelper.GenerateKey();string iv = AesHelper.GenerateIV();string cipherText = AesHelper.Encrypt(plainText, key, iv);string decryptedText = AesHelper.Decrypt(cipherText, key, iv);

Console.WriteLine("Plain text: {0}", plainText);
Console.WriteLine("Cipher text: {0}", cipherText);
Console.WriteLine("Decrypted text: {0}", decryptedText);

2、AES对称加密算法(ECB模式,无需初始化向量)

usingSystem;usingSystem.IO;usingSystem.Security.Cryptography;usingSystem.Text;namespaceAesHelper{publicclassAes{/// <summary>/// AES算法的keysize有一定限制。/// 具体来说,AES算法支持的keysize为 128 bits、192 bits 和 256 bits,而且只能以16 bits(即2个字节)为步长递增。/// 也就是说,支持的有效的 keysize 可以是:128、160、192、224 或 256。/// 需要注意的是,AES算法的 keysize 越大,加密强度越高,但同时也会增加加密运算所需的时间和计算资源。/// 因此,在实际应用中,需要根据实际需求和环境对 keysize 进行合理的选择。/// </summary>privatestaticreadonlyint KeySize =256;/// <summary>/// 生成秘钥/// </summary>/// <returns></returns>publicstaticstringGenerateKey(){using(var aes = Aes.Create()){
                aes.KeySize = KeySize;
                aes.Mode = CipherMode.ECB;// ECB 模式无需 IV 向量
                aes.Padding = PaddingMode.PKCS7;

                aes.GenerateKey();return Convert.ToBase64String(aes.Key);}}/// <summary>/// 加密/// </summary>/// <param name="plainText"></param>/// <param name="key"></param>/// <returns></returns>publicstaticstringEncrypt(string plainText,string key){using(var aes = Aes.Create()){
                aes.KeySize = KeySize;
                aes.Mode = CipherMode.ECB;// ECB 模式无需 IV 向量
                aes.Padding = PaddingMode.PKCS7;
                aes.Key = Convert.FromBase64String(key);ICryptoTransform encryptor = aes.CreateEncryptor();byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);byte[] cipherBytes = encryptor.TransformFinalBlock(plainBytes,0, plainBytes.Length);return Convert.ToBase64String(cipherBytes);}}/// <summary>/// 解密/// </summary>/// <param name="cipherText"></param>/// <param name="key"></param>/// <returns></returns>publicstaticstringDecrypt(string cipherText,string key){using(var aes = Aes.Create()){
                aes.KeySize = KeySize;
                aes.Mode = CipherMode.ECB;// ECB 模式无需 IV 向量
                aes.Padding = PaddingMode.PKCS7;
                aes.Key = Convert.FromBase64String(key);ICryptoTransform decryptor = aes.CreateDecryptor();byte[] cipherBytes = Convert.FromBase64String(cipherText);byte[] plainBytes = decryptor.TransformFinalBlock(cipherBytes,0, cipherBytes.Length);return Encoding.UTF8.GetString(plainBytes);}}}}

2.1、加解密测试

string key = AesHelper.GenerateKey();string plainText ="Hello, world!";string cipherText = AesHelper.Encrypt(plainText, key);
Console.WriteLine(cipherText);string decryptedPlainText = AesHelper.Decrypt(cipherText, key);
Console.WriteLine(decryptedPlainText);

3、RSA非对称加密算法

usingSystem;usingSystem.IO;usingSystem.Security.Cryptography;usingSystem.Text;namespaceRSA{/// <summary>/// 在C#中,RSACryptoServiceProvider的KeySize属性可以设置为任意偶数位的值,/// 建议使用2048位或更长的密钥长度以提供足够的安全性,典型情况下,RSA密钥的长度为2048位。/// 尽管在理论上可以使用较小的密钥长度来加速RSA操作,但是使用较小的密钥可能会使RSA易受到攻击,/// 因此不推荐使用少于2048位的密钥长度。为了确保数据的安全,应该使用更长的密钥(根据实际需求选择),并定期更换密钥。/// ----------------------------/// RSA验证签名的作用是确保接收到的数据没有经过篡改,并且确实是由发送方发送的。/// 在数字通信中,攻击者可能会截取通信并修改消息内容,然后将其发送给接收方,导致接收方无法正确解释消息或采取错误的行动。/// 通过使用RSA签名,发送方可以对消息进行数字签名,这个数字签名是通过使用发送方的私钥生成的。/// 接收方可以使用发送方的公钥来验证数字签名,如果验证成功,就意味着消息没有被篡改,并且确实是由发送方发送的。/// 如果验证失败,接收方就可以确定消息已被篡改或不是由发送方发送的。/// 该过程确保了消息的完整性和真实性,防止了中间人攻击。因此,在数字通信中,RSA验证签名是一种非常重要的安全机制。/// ----------------------------/// 【注意】:为了与jsencrypt.min.js互换数据,需要将生成的 publicKey 和 privateKey 中的 = 去除/// </summary>publicclassRsaHelper{/// <summary>/// 生成公钥和私钥/// </summary>/// <param name="keySize">密钥大小</param>/// <param name="privateKey">输出私钥</param>/// <param name="publicKey">输出公钥</param>publicstaticvoidGenerateKeys(int keySize,outstring privateKey,outstring publicKey){using(var rsa =newRSACryptoServiceProvider(keySize)){
                privateKey = Convert.ToBase64String(rsa.ExportRSAPrivateKey());
                publicKey = Convert.ToBase64String(rsa.ExportRSAPublicKey());}}/// <summary>/// 加密/// </summary>/// <param name="publicKey">公钥</param>/// <param name="data">要加密的数据</param>/// <returns>加密后的数据</returns>publicstaticstringEncrypt(string publicKey,string data){using(var rsa =newRSACryptoServiceProvider()){
                rsa.ImportRSAPublicKey(Convert.FromBase64String(publicKey),out _);var bytes = Encoding.UTF8.GetBytes(data);var encryptedBytes = rsa.Encrypt(bytes, RSAEncryptionPadding.Pkcs1);return Convert.ToBase64String(encryptedBytes);}}/// <summary>/// 解密/// </summary>/// <param name="privateKey">私钥</param>/// <param name="data">要解密的数据</param>/// <returns>解密后的数据</returns>publicstaticstringDecrypt(string privateKey,string data){using(var rsa =newRSACryptoServiceProvider()){
                rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey),out _);var encryptedBytes = Convert.FromBase64String(data);var decryptedBytes = rsa.Decrypt(encryptedBytes, RSAEncryptionPadding.Pkcs1);return Encoding.UTF8.GetString(decryptedBytes);}}/// <summary>/// RSA私钥签名/// </summary>/// <param name="privateKey">私钥</param>/// <param name="data">要签名的数据</param>/// <returns>签名数据</returns>publicstaticstringSignData(string privateKey,string data){using(var rsa =newRSACryptoServiceProvider()){
                rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey),out _);var bytes = Encoding.UTF8.GetBytes(data);var signatureBytes = rsa.SignData(bytes, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);return Convert.ToBase64String(signatureBytes);}}/// <summary>/// 验证RSA签名/// </summary>/// <param name="publicKey">公钥</param>/// <param name="data">原始数据</param>/// <param name="signatureData">签名数据</param>/// <returns></returns>publicstaticboolVerifyData(string publicKey,string data,string signatureData){using(var rsa =newRSACryptoServiceProvider()){
                rsa.ImportRSAPublicKey(Convert.FromBase64String(publicKey),out _);var bytes = Encoding.UTF8.GetBytes(data);var signatureBytes = Convert.FromBase64String(signatureData);return rsa.VerifyData(bytes, signatureBytes, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);}}}}

3.1、加解密测试

//生成公钥和私钥
RsaHelper.GenerateKeys(2048,outvar privateKey,outvar publicKey);//加密var data ="Hello World!";string encryptedData = RsaHelper.Encrypt(publicKey, data);//解密string decryptedData = RsaHelper.Decrypt(privateKey, encryptedData);//签名string signatureData = RsaHelper.SignData(privateKey, data);//验证签名bool isVerify = RsaHelper.VerifyData(publicKey, data, signatureData);

Console.WriteLine($"公钥:{publicKey} \n");
Console.WriteLine($"私钥:{privateKey} \n");
Console.WriteLine($"密文:{encryptedData} \n");
Console.WriteLine($"解密明文:{decryptedData} \n");
Console.WriteLine($"签名:{signatureData} \n");
Console.WriteLine($"验证签名:{isVerify} \n");

三、前端代码实现

在这里插入图片描述
在这里插入图片描述

已打包成资源供各位下载查阅:https://download.csdn.net/download/qq_41970599/87898493

标签: c# 开发语言

本文转载自: https://blog.csdn.net/qq_41970599/article/details/131134770
版权归原作者 com-ljf 所有, 如有侵权,请联系我们删除。

“C# 实现对称加密算法(AES)与非对称加密算法(RSA),包含前端加密对应算法实现”的评论:

还没有评论