C# 实现对称加密算法(AES)与非对称加密算法(RSA),包含前端加密对应算法实现
C# 实现对称加密算法(AES)与非对称加密算法(RSA),包含前端对应加密算法实现
- 一、两者的含义
- 1、对称加密:
- 2、非对称加密:
- 二、后端代码实现
- 1、AES对称加密算法(CBC模式,多一个初始化向量,安全性高)
- 1.1、加解密测试:
- 2、AES对称加密算法(ECB模式,无需初始化向量)
- 2.1、加解密测试
- 3、RSA非对称加密算法
- 3.1、加解密测试
- 三、前端代码实现
一、两者的含义
1、对称加密:
一种既简单速度又快的加密方式,加密与解密使用的都是同一个密钥,别名又叫做:单密钥加密;对称加密有很多公开算法,并且因为它效率很高,所以适用于加密大量数据的场合;但其密钥的传输过程是不安全的,并且容易被破解,密钥管理起来也相对麻烦。
2、非对称加密:
需要两个密钥来进行加密和解密,这两个密钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥),如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。加密密钥是公开的,密钥的分配和管理就很简单,而且能够很容易地实现数字签名,因此最适合于电子商务应用的需要;但是如果对大数量进行操作,计算量特别大,速度远远比不上对称加密。
详细请阅读这篇文章 https://blog.csdn.net/qq_38556796/article/details/126706393
二、后端代码实现
1、AES对称加密算法(CBC模式,多一个初始化向量,安全性高)
IV:初始化向量,配合秘钥一起使用,每次加密时随机生成,解密需要秘钥与IV一起才能解密
代码如下:
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Aes { public class AesHelper { private const int KEY_SIZE = 256; private const int BLOCK_SIZE = 128; private const string KEY_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; private const string IV_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; public static string Encrypt(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 = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { cs.Write(plainBytes, 0, plainBytes.Length); } byte[] encryptedBytes = ms.ToArray(); return Convert.ToBase64String(encryptedBytes); } } } public static string Decrypt(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 = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write)) { cs.Write(cipherBytes, 0, cipherBytes.Length); } byte[] decryptedBytes = ms.ToArray(); return Encoding.UTF8.GetString(decryptedBytes); } } } public static string GenerateKey() { Random random = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 0; i
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模式,无需初始化向量)
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace AesHelper { public class Aes { /// /// AES算法的keysize有一定限制。 /// 具体来说,AES算法支持的keysize为 128 bits、192 bits 和 256 bits,而且只能以16 bits(即2个字节)为步长递增。 /// 也就是说,支持的有效的 keysize 可以是:128、160、192、224 或 256。 /// 需要注意的是,AES算法的 keysize 越大,加密强度越高,但同时也会增加加密运算所需的时间和计算资源。 /// 因此,在实际应用中,需要根据实际需求和环境对 keysize 进行合理的选择。 /// private static readonly int KeySize = 256; /// /// 生成秘钥 /// /// public static string GenerateKey() { 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); } } /// /// 加密 /// /// /// /// public static string Encrypt(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); } } /// /// 解密 /// /// /// /// public static string Decrypt(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非对称加密算法
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace RSA { /// /// 在C#中,RSACryptoServiceProvider的KeySize属性可以设置为任意偶数位的值, /// 建议使用2048位或更长的密钥长度以提供足够的安全性,典型情况下,RSA密钥的长度为2048位。 /// 尽管在理论上可以使用较小的密钥长度来加速RSA操作,但是使用较小的密钥可能会使RSA易受到攻击, /// 因此不推荐使用少于2048位的密钥长度。为了确保数据的安全,应该使用更长的密钥(根据实际需求选择),并定期更换密钥。 /// ---------------------------- /// RSA验证签名的作用是确保接收到的数据没有经过篡改,并且确实是由发送方发送的。 /// 在数字通信中,攻击者可能会截取通信并修改消息内容,然后将其发送给接收方,导致接收方无法正确解释消息或采取错误的行动。 /// 通过使用RSA签名,发送方可以对消息进行数字签名,这个数字签名是通过使用发送方的私钥生成的。 /// 接收方可以使用发送方的公钥来验证数字签名,如果验证成功,就意味着消息没有被篡改,并且确实是由发送方发送的。 /// 如果验证失败,接收方就可以确定消息已被篡改或不是由发送方发送的。 /// 该过程确保了消息的完整性和真实性,防止了中间人攻击。因此,在数字通信中,RSA验证签名是一种非常重要的安全机制。 /// ---------------------------- /// 【注意】:为了与jsencrypt.min.js互换数据,需要将生成的 publicKey 和 privateKey 中的 = 去除 /// public class RsaHelper { /// /// 生成公钥和私钥 /// /// 密钥大小 /// 输出私钥 /// 输出公钥 public static void GenerateKeys(int keySize, out string privateKey, out string publicKey) { using (var rsa = new RSACryptoServiceProvider(keySize)) { privateKey = Convert.ToBase64String(rsa.ExportRSAPrivateKey()); publicKey = Convert.ToBase64String(rsa.ExportRSAPublicKey()); } } /// /// 加密 /// /// 公钥 /// 要加密的数据 /// 加密后的数据 public static string Encrypt(string publicKey, string data) { using (var rsa = new RSACryptoServiceProvider()) { rsa.ImportRSAPublicKey(Convert.FromBase64String(publicKey), out _); var bytes = Encoding.UTF8.GetBytes(data); var encryptedBytes = rsa.Encrypt(bytes, RSAEncryptionPadding.Pkcs1); return Convert.ToBase64String(encryptedBytes); } } /// /// 解密 /// /// 私钥 /// 要解密的数据 /// 解密后的数据 public static string Decrypt(string privateKey, string data) { using (var rsa = new RSACryptoServiceProvider()) { rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out _); var encryptedBytes = Convert.FromBase64String(data); var decryptedBytes = rsa.Decrypt(encryptedBytes, RSAEncryptionPadding.Pkcs1); return Encoding.UTF8.GetString(decryptedBytes); } } /// /// RSA私钥签名 /// /// 私钥 /// 要签名的数据 /// 签名数据 public static string SignData(string privateKey, string data) { using (var rsa = new RSACryptoServiceProvider()) { 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); } } /// /// 验证RSA签名 /// /// 公钥 /// 原始数据 /// 签名数据 /// public static bool VerifyData(string publicKey, string data, string signatureData) { using (var rsa = new RSACryptoServiceProvider()) { 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, out var privateKey, out var 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
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理!
部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!
图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!