RSA加密的基本常识和封装类
RSA加密的基本常识和封装类
RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,广泛应用于数据加密、数字签名和密钥交换等领域。在RSA加密封装中,主要涉及生成密钥对、加密和解密的过程。
一、 RSA加密封装的过程
1. 生成密钥对: RSA算法使用一对密钥,包括公钥和私钥。公钥用于加密数据,私钥用于解密数据。生成密钥对的过程如下:
a. 选择两个大素数: 首先选择两个足够大的不同素数,通常用p和q来表示。
b. 计算n和Φ(n): 计算n = p * q,以及Φ(n) = (p-1) * (q-1)。其中,n是公钥和私钥的一部分,Φ(n)在后续计算中会用到。
c. 选择公钥e: 选择一个整数e(1 < e < Φ(n)),且e与Φ(n)互质,即e和Φ(n)的最大公约数为1。e作为公钥的一部分,用于加密数据。
d. 计算私钥d: 计算e关于Φ(n)的模反元素d,使得 (d * e) % Φ(n) = 1。d作为私钥的一部分,用于解密数据。
最终,得到的公钥是(n, e),私钥是(n, d)。
2. 加密过程: RSA加密使用公钥进行加密,加密的过程如下:
a. 将数据转换为整数: 将要加密的数据转换为一个整数,通常使用编码方式(如UTF-8)将数据转换为字节数组,再将字节数组转换为一个大整数。
b. 使用公钥加密: 使用公钥中的参数n和e,对整数进行加密运算,得到密文。加密运算的公式为:密文 = 明文^e % n。
3. 解密过程: RSA解密使用私钥进行解密,解密的过程如下:
a. 获取密文: 获取到被加密的密文。
b. 使用私钥解密: 使用私钥中的参数n和d,对密文进行解密运算,得到原始数据。解密运算的公式为:原始数据 = 密文^d % n。
需要注意的是,RSA算法中,加密和解密的整数运算非常耗时,因此在实际应用中通常只用RSA加密对称密钥等少量数据,再使用对称加密算法(如AES)对大量数据进行加密。这样可以兼顾RSA的安全性和对称加密的高效性。
二、RSA的应用
- 数据传输安全: RSA广泛用于保证敏感数据在网络传输过程中的安全性。在例如网上银行、电子商务等应用中,用户的敏感信息(如密码、身份证号等)在传输过程中需要使用RSA加密,确保只有授权用户能够解密并读取这些信息,从而避免信息被恶意截获或篡改。
- 数字签名: RSA可以用于生成数字签名,用于验证数据的完整性和来源。在数字签名中,使用私钥对数据进行签名,而任何人都可以使用公钥验证签名的有效性。这在保证文件的完整性和防止数据篡改方面非常有用,例如软件下载时的数字签名验证。
- 安全登录: 在身份验证过程中,用户的登录密码通常需要进行加密传输,以免密码在网络传输过程中被截获。RSA可用于将登录密码加密,并在服务器端使用私钥进行解密,从而保证登录密码的安全传输。
- 数字证书: RSA用于生成数字证书,用于证明实体(如网站、应用程序等)的身份和安全性。数字证书中包含实体的公钥,由数字证书颁发机构(CA)签名,用于验证实体的身份和公钥的合法性。
- 加密密钥交换: 在对称加密中,加密密钥需要在通信双方之间进行安全交换。RSA可以用于在通信开始时安全地交换对称加密密钥,从而确保加密密钥不被中间人攻击截获或篡改。
应用场景中的代码示例:
生成RSA密钥对
using System.Security.Cryptography;
using (var rsa = new RSACryptoServiceProvider(2048))
{
// 获取公钥和私钥
string publicKey = rsa.ToXmlString(false);
string privateKey = rsa.ToXmlString(true);
// 这里只是简单示例,实际应用中需要妥善保管私钥
}
使用公钥加密数据
// 使用公钥加密数据
using System.Security.Cryptography;
string publicKey = "......"; // 从证书或其他安全渠道获取公钥
byte[] data = Encoding.UTF8.GetBytes("敏感数据");
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.FromXmlString(publicKey);
byte[] encryptedData = rsa.Encrypt(data, false);
// 将加密后的数据传输给接收方
}
使用私钥解密数据
// 使用私钥解密数据
using System.Security.Cryptography;
string privateKey = "......"; // 仅在安全的环境下获取私钥
byte[] encryptedData = ......; // 从接收方获取加密后的数据
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.FromXmlString(privateKey);
byte[] decryptedData = rsa.Decrypt(encryptedData, false);
// 处理解密后的数据
string originalData = Encoding.UTF8.GetString(decryptedData);
}
以上示例演示了RSA密钥对的生成,以及使用公钥加密数据和使用私钥解密数据的过程。在实际应用中,通常需要更多的处理来确保数据的安全性和正确性,例如数据填充、数字签名验证等。同时,由于RSA加密运算较为耗时,通常将RSA与对称加密算法结合使用,以保证加密过程的高效性和安全性。
三、RSA加密封装类
/// <summary>
/// RSA ECC
/// 可逆非对称加密
/// 非对称加密算法的优点是密钥管理很方便,缺点是速度慢。
/// </summary>
public class RsaEncrypt
{
/// <summary>
/// 获取加密/解密对
/// 给你一个,是无法推算出另外一个的
///
/// Encrypt Decrypt
/// </summary>
/// <returns>Encrypt Decrypt</returns>
public static KeyValuePair<string, string> GetKeyPair()
{
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
string publicKey = RSA.ToXmlString(false); //在C#中只实现了 公钥加密 私钥解密 如果有需要其他场景的,需要引入一个第三方dll
string privateKey = RSA.ToXmlString(true);
return new KeyValuePair<string, string>(publicKey, privateKey);
}
/// <summary>
/// 加密:内容+加密key
///
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey">加密key</param>
/// <returns></returns>
public static string Encrypt(string content, string encryptKey)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(encryptKey);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsa.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
/// <summary>
/// 解密 内容+解密key
/// </summary>
/// <param name="content"></param>
/// <param name="decryptKey">解密key</param>
/// <returns></returns>
public static string Decrypt(string content, string decryptKey)
{
byte[] dataToDecrypt = Convert.FromBase64String(content);
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString(decryptKey);
byte[] resultBytes = RSA.Decrypt(dataToDecrypt, false);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
return ByteConverter.GetString(resultBytes);
}
/// <summary>
/// 可以合并在一起的,每次产生一组新的密钥
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey">加密key</param>
/// <param name="decryptKey">解密key</param>
/// <returns>加密后结果</returns>
private static string Encrypt(string content, out string publicKey, out string privateKey)
{
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
publicKey = rsaProvider.ToXmlString(false);
privateKey = rsaProvider.ToXmlString(true);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsaProvider.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
}