小编这些日子碰到一个需求,当自己公司的程序与其他公司的程序需要关联的时候,需要接口关联,但是呢有些敏感的数据双方也都不希望暴露出来,那么就用到了C#的RSA加密解密功能,来,让小编带你讲解讲解。
RSA生成公钥和私钥
public void getKey()
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
using (StreamWriter writer = new StreamWriter("G://PrivateKey.xml"))
{
writer.WriteLine(rsa.ToXmlString(true));
}
using (StreamWriter writer = new StreamWriter("G://PublicKey.xml"))
{
writer.WriteLine(rsa.ToXmlString(false));
}
}
该方法是获取密钥,其作用就是生成公钥和私钥的文件,文件中的内容就是公钥和私钥。一般而言,公钥是用来加密的,而私钥是用来解密的,所以公钥对方公司可以给我们公司,我们将内容通过公司提供的公钥进行加密,然后把加密内容传给对方公司,对方通过对应的私钥进行解密就好了,所以公钥一般可以透露,但是私钥最好不要透露。
RSA加密
public string Encrypt(string str, string key)
{
using (var rsaProvider = new RSACryptoServiceProvider())
{
var inputBytes = Encoding.UTF8.GetBytes(str);
rsaProvider.FromXmlString(key);
int bufferSize = (rsaProvider.KeySize / 8) - 11;
var buffer = new byte[bufferSize];
using (MemoryStream inputStream = new MemoryStream(inputBytes),
outputStream = new MemoryStream())
{
while (true)
{
int readSize = inputStream.Read(buffer, 0, bufferSize);
if (readSize <= 0)
{
break;
}
var temp = new byte[readSize];
Array.Copy(buffer, 0, temp, 0, readSize);
var encryptedBytes = rsaProvider.Encrypt(temp, false);
outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
}
return Convert.ToBase64String(outputStream.ToArray());
}
}
}
RSA解密
public string Decrypt(string str, string key)
{
using (var rsaProvider = new RSACryptoServiceProvider())
{
var inputBytes = Convert.FromBase64String(str);
rsaProvider.FromXmlString(key);
int bufferSize = rsaProvider.KeySize / 8;
var buffer = new byte[bufferSize];
using (MemoryStream inputStream = new MemoryStream(inputBytes),
outputStream = new MemoryStream())
{
while (true)
{
int readSize = inputStream.Read(buffer, 0, bufferSize);
if (readSize <= 0)
{
break;
}
var temp = new byte[readSize];
Array.Copy(buffer, 0, temp, 0, readSize);
var rawBytes = rsaProvider.Decrypt(temp, false);
outputStream.Write(rawBytes, 0, rawBytes.Length);
}
return Encoding.UTF8.GetString(outputStream.ToArray());
}
}
}
小编参考了很多,但是最开始不是出现这个问题就是出现那个问题,经常是字符串内容超过了长度啊,还有有时可行有时不可行的,最后新来的同事给了我这个方法,我才一路畅通无阻,比我大了两岁真的还是很牛啊,不过也提醒了自己基础很重要,否则自己和对方公司交接的时候恐怕自己都不知道怎么完成此类的思路和逻辑。
时隔3年有同志和小编交流了关于Java中私钥加密,C#公钥解密的问题,小编并没有帮助其找出问题,最后是同志自己找出来的并分享给了小编,看代码
/// <summary>
/// 用公钥解密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string decryptByPublicKey(string data, string key)
{
string pubKey = key.Trim();
string xmlPublicKey = RSAPublicKeyJava2DotNet(pubKey);
MemoryStream output = new MemoryStream();
RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
publicRsa.FromXmlString(xmlPublicKey);
AsymmetricKeyParameter keyPair = DotNetUtilities.GetRsaPublicKey(publicRsa);
//转换密钥
// AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(publicRsa);
IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致
c.Init(false, keyPair); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
data = data.Trim();
byte[] DataToEncrypt = Convert.FromBase64String(data);
int inputLen = DataToEncrypt.Length;
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0)
{
if (inputLen - offSet > 128)
{
cache= c.DoFinal(DataToEncrypt, offSet, 128);//解密
}
else
{
cache = c.DoFinal(DataToEncrypt, offSet, 128);//解密
}
output.Write(cache, 0, cache.Length);
i++;
offSet = i * 128;
}
byte[] dBytes = output.ToArray();
return Encoding.UTF8.GetString(dBytes);
}
IBufferedCipher c = CipherUtilities.GetCipher(“RSA/ECB/PKCS1Padding”);// 参数与Java中加密解密的参数一致
正所谓独学而无友,则孤陋而寡闻,感谢同志的分享。