我试图在 dot net core 中使用 RSA 加密一串信息,目的是只加密纯文本并将其发送到运行 PHP/MySQL 的服务器并存储加密信息。服务器不会发送任何确认或其他数据作为回复,因此这是一种单向通信(如果我可以说的话)。 为此,我提供了三种方法,一种生成 2048 的 Keypair,并将信息存储在 List(不是 RSAParameter)中并返回,另外两种方法是加密和解密方法。 问题是加密工作正常,公钥作为模数,公共指数作为指数,而在解密时,私钥作为模数,公共指数作为指数,私有指数“D”作为私有指数,我收到异常“模数和指数是必填字段”,如果我删除“D”,则会抛出“此密钥大小的无效数据长度”的异常,我不太擅长 RSA 的数学方面。我还尝试了各种获取字节的方法(编码、隐蔽等)。以下是我使用的三种方法。
生成密钥对等参数的方法:
public static List<string> RsaKeyGen()
{
List<string> keyPair = new List<string>();
RSA rsa = RSA.Create(2048);
RSAParameters param = rsa.ExportParameters(true);
keyPair.Add(Convert.ToBase64String(rsa.ExportRSAPrivateKey()));
keyPair.Add(Convert.ToBase64String(rsa.ExportRSAPublicKey()));
keyPair.Add(Convert.ToBase64String(param.Exponent));
keyPair.Add(Convert.ToBase64String(param.D));
return keyPair;
}
加密方法
public static string RsaEncrypt(byte[] PUBLIC_KEY ,byte[] EXPONENT, string text)
{
RSA rsa = RSA.Create(2048);
RSAParameters param = new RSAParameters();
param.Modulus = PUBLIC_KEY;
param.Exponent = EXPONENT;
rsa.ImportParameters(param);
return Convert.ToBase64String(rsa.Encrypt(Convert.FromBase64String(text), RSAEncryptionPadding.Pkcs1));
}
最后是解密方法:
public static string RsaDecrypt(byte[] PRIVATE_KEY, byte[] EXPONENT, byte[] PEXPO , string DATA)
{
RSA rsa = RSA.Create(2048);
RSAParameters param = new RSAParameters();
param.Modulus = PRIVATE_KEY;
param.Exponent = EXPONENT;
param.D = PEXPO;
rsa.ImportParameters(param);
return Convert.ToBase64String(rsa.Decrypt(Convert.FromBase64String(DATA), RSAEncryptionPadding.Pkcs1));
}
答案 0 :(得分:0)
这是一个以您的代码为起点的最小工作示例 (MWE)。正如我所评论的,您只需要导入您的私钥/公钥。无需提供 Exponent
或 D
。
(顺便说一句,您正在到处转换二进制和字符串类型。我建议您将整个 RSA 代码基于 byte[]
,并且仅在需要时才转换回字符串到。下面的代码是为了匹配你提供的签名)
public class RsaMwe
{
public static bool Demo()
{
var strings = RsaKeyGen();
var privKey = Convert.FromBase64String(strings[0]);
var pubKey = Convert.FromBase64String(strings[1]);
var clearText = "Hello World!";
var clearText64 = Convert.ToBase64String(Encoding.Default.GetBytes(clearText));
var encrypted64 = RsaEncrypt(pubKey, clearText64);
var decrypted64 = RsaDecrypt(privKey, encrypted64);
return clearText == Encoding.Default.GetString(Convert.FromBase64String(decrypted64));
}
public static List<string> RsaKeyGen()
{
List<string> keyPair = new List<string>();
using RSA rsa = RSA.Create(2048);
keyPair.Add(Convert.ToBase64String(rsa.ExportRSAPrivateKey()));
keyPair.Add(Convert.ToBase64String(rsa.ExportRSAPublicKey()));
return keyPair;
}
public static string RsaEncrypt(byte[] pubKey, string clearText64)
{
using RSA rsa = RSA.Create(2048);
rsa.ImportRSAPublicKey(pubKey, out _);
return Convert.ToBase64String(rsa.Encrypt(Convert.FromBase64String(clearText64), RSAEncryptionPadding.Pkcs1));
}
public static string RsaDecrypt(byte[] privKey, string cypherText64)
{
using RSA rsa = RSA.Create(2048);
rsa.ImportRSAPrivateKey(privKey, out _);
return Convert.ToBase64String(rsa.Decrypt(Convert.FromBase64String(cypherText64), RSAEncryptionPadding.Pkcs1));
}
}
另外不要忘记处理您的 RSA 对象。