C# 实现 Rsa字符串非对称加密简单例子
C# Rsa加密帮助类\Rsa字符串非对称加密简单例子
本代码是应用于以前就职的一家公司里 两个系统对接加密实现的加密算法,对面是java语言 我这边是场.net 折腾了很久才实现对接成功,这段核心的rsa加密代码的来源代码里备注的有,代码被我改的有点乱,封装成了一个类原装稍微又些区别,代码实测可用就是需要引用BouncyCastle 的组件库 建议nuget上直接引用,单独引用的话需要引用多个dll 少了貌似不行。
- 加密例子
string p="我是要加密的字符串";
string result= Common.RsaCrypto.Encrypt(p)
- 解密例子
p =Common.RsaCrypto.Decrypt(result);
网上找到的一段rsa的帮助类 已在实际落地项目中验证过可用性
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Common
{
////// Rsa加密解密-可逆非对称加密(公钥加密算法)
/// RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。
/// 安全性好,性能不如Des
public static class RsaCrypto
{
public static String KEY_ALGORITHM = "RSA";
#region 加密解密方式一:加密密钥和解密密钥相同
//参考:https://www.cnblogs.com/guohu/p/5562759.html
////// 秘钥:加密、解密(秘钥相同,注意保存)
//////private static CspParameters GetCspKey()
{
CspParameters param = new CspParameters
{
KeyContainerName = KEY_ALGORITHM//密匙容器的名称,保持加密解密一致才能解密成功
};
return param;
}
////// 加密
//////明文///编码方式///密文
public static string Encrypt(string palinData,
EncodingStrOrByte.EncodingType encodingType
= EncodingStrOrByte.EncodingType.UTF8)
{
if (string.IsNullOrWhiteSpace(palinData)) return null;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(GetCspKey()))
{
byte[] bytes = EncodingStrOrByte.GetByte(palinData, encodingType); //将要加密的字符串转换为指定编码的字节数组
byte[] encryptData = rsa.Encrypt(bytes, false);//将加密后的字节数据转换为新的加密字节数组
return Convert.ToBase64String(encryptData);//将加密后的字节数组转换为字符串
}
}
////// 解密
//////密文///编码方式///明文
public static string Decrypt(string encryptData,
EncodingStrOrByte.EncodingType encodingType
= EncodingStrOrByte.EncodingType.UTF8)
{
if (string.IsNullOrWhiteSpace(encryptData)) return null;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(GetCspKey()))
{
byte[] bytes = Convert.FromBase64String(encryptData);
byte[] palinData = rsa.Decrypt(bytes, false);
return EncodingStrOrByte.GetString(palinData, encodingType);
}
}
#endregion
#region 加密解密方式二:公钥加密/私钥解密
#region 公/私密钥
//openssl genrsa -out rsa_1024_priv.pem 1024
private static readonly string _privateKey = @"MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALVcQjHHc35w4s9K3nYTkp/
eS7VGi/8X
kNbQwZSAKkgoIbj4NfxMzxumvmhI1UNFYpHKhvYV1Fms5a1aC47D4XytekRI9zFQrYb9kTXVTf0XARmdwv
PoGk/JmWdsCpxrV8AAVzz8xY0m6OktpBpqcweMBmd72hSX9faniQet2ul9AgMBAAECgYAPsunD91jnBAy
OFxQEspMJpat2CKJLtZWDEtT+7s06K8cnhMzfhyKSaS+oRU24ogPzTM279Y3JKW9EPzwq4ofdJnjjpef+yq
ToYey9M5YvhEsJ/KjoeEMCMJ8VEVXaeL6OOIImncKWk9fwDxPMqcKMkmQt8F5j7gxhdp6a+LBCXQJBAPEe
xjvAu9tN22V4D3GWd3rxyE2+2xdA/7BZ1M3/UPozrfifPdbKcsdzpXkOqbXukhAcRS9OKwMjceIeGfCIWoMC
QQDAjWV3l0SO4ixvwAU1CgH0knD1oh9Z9x7tjdXWGB6Du0oS5KpzaG2cZmwjPTsGaV5KvQnFVYWnCguyr
/HgvGv/AkEA1/CsrjTUyPn4Q+57Pkn4JTZGIkKMKk4+72v0JqzCk+EWrDPJCQT0OGX8yubz3IiVbTI0T8Jcy
QnEYzJ8HquvCwJBALE4sr4aZMhZlOqZwnEpr9kJe5woxlBIaZfdJoYxlsxJ8ghnnBYydEgx4K+iaJQjIN0LFlYg
u62dSl0BIU9mPMMCQQCQ5dWzJrTrMWAJh9JXw0PSp55we2PC6x36wvGp391lrnSUPP638HcDvlW6q/
RaXeE/ZJKf3lhlBrcZszAowYIH".Replace("\n", "");
//openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
private static readonly string _publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5UK1mrA9U5iXYS9OmQlYL7N0Okg/gzDtwS
WPnyLlgpy
7EC419jQTaWQY2rCqsH1jmO4TrT55keKkchK3s7PKvpnM0hjn4QpzvDJzKaCvESuVAbpGekkYAV
rxLb8Or
S68f0cc+WCOroyKTDfgHxbgQWqDCsScnE/UBsn6Xii/thQIDAQAB".Replace("\n", "");
#endregion
////// 公钥加密
//////明文///编码方式///string:密文
public static string EncryptByPublicKey(string palinData,
EncodingStrOrByte.EncodingType encodingType
= EncodingStrOrByte.EncodingType.UTF8)
{
if (string.IsNullOrWhiteSpace(palinData)) return null;
RSA rsa = CreateRsaFromPublicKey(_publicKey);
byte[] palinDataBytes = EncodingStrOrByte.GetByte(palinData, encodingType);
byte[] encryptDataBytes = rsa.EncryptValue(palinDataBytes);
return Convert.ToBase64String(encryptDataBytes);
}
////// 私钥解密
//////密文///编码方式///string:明文
(string encryptData, EncodingStrOrByte.EncodingType encodingType
= EncodingStrOrByte.EncodingType.UTF8)
{
if (string.IsNullOrWhiteSpace(encryptData)) return null;
RSA rsa = CreateRsaFromPrivateKey(_privateKey);
byte[] encryptDataBytes = Convert.FromBase64String(encryptData);
byte[] palinDataBytes = rsa.DecryptValue(encryptDataBytes);
return EncodingStrOrByte.GetString(palinDataBytes, encodingType);
}
////// 创建私钥
private static RSA CreateRsaFromPrivateKey(string privateKey)
{
var privateKeyBits = Convert.FromBase64String(privateKey);
var rsa = RSA.Create();
var RSAparams = new RSAParameters();
using (var binr = new BinaryReader(new MemoryStream(privateKeyBits)))
{
byte bt = 0;
ushort twobytes = 0;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130)
binr.ReadByte();
else if (twobytes == 0x8230)
binr.ReadInt16();
else
throw new Exception("Unexpected value read binr.ReadUInt16()");
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102)
throw new Exception("Unexpected version");
bt = binr.ReadByte();
if (bt != 0x00)
throw new Exception("Unexpected value read binr.ReadByte()");
RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
}
rsa.ImportParameters(RSAparams);
return rsa;
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02)
{ return count; }
bt = binr.ReadByte();
if (bt == 0x81)
{ count = binr.ReadByte(); }
else if (bt == 0x82)
{
highbyte = binr.ReadByte();
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else { count = bt; }
while (binr.ReadByte() == 0x00)
{
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current);
return count;
}
////// 创建公钥
private static RSA CreateRsaFromPublicKey(string publicKeyString)
{
byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
byte[] x509key;
byte[] seq = new byte[15];
int x509size;
x509key = Convert.FromBase64String(publicKeyString);
x509size = x509key.Length;
using (var mem = new MemoryStream(x509key))
{
using (var binr = new BinaryReader(mem))
{
byte bt = 0;
ushort twobytes = 0;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130)
binr.ReadByte();
else if (twobytes == 0x8230)
binr.ReadInt16();
else
return null;
seq = binr.ReadBytes(15);
if (!CompareBytearrays(seq, SeqOID))
return null;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8103)
binr.ReadByte();
else if (twobytes == 0x8203)
binr.ReadInt16();
else
return null;
bt = binr.ReadByte();
if (bt != 0x00)
return null;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130)
binr.ReadByte();
else if (twobytes == 0x8230)
binr.ReadInt16();
else
return null;
twobytes = binr.ReadUInt16();
byte lowbyte = 0x00;
byte highbyte = 0x00;
if (twobytes == 0x8102)
lowbyte = binr.ReadByte();
else if (twobytes == 0x8202)
{
highbyte = binr.ReadByte();
lowbyte = binr.ReadByte();
}
else
return null;
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
int modsize = BitConverter.ToInt32(modint, 0);
int firstbyte = binr.PeekChar();
if (firstbyte == 0x00)
{
binr.ReadByte();
modsize -= 1;
}
byte[] modulus = binr.ReadBytes(modsize);
if (binr.ReadByte() != 0x02)
return null;
int expbytes = (int)binr.ReadByte();
byte[] exponent = binr.ReadBytes(expbytes);
var rsa = RSA.Create();
var rsaKeyInfo = new RSAParameters
{
Modulus = modulus,
Exponent = exponent
};
rsa.ImportParameters(rsaKeyInfo);
return rsa;
}
}
}
private static bool CompareBytearrays(byte[] a, byte[] b)
{
if (a.Length != b.Length)
return false;
int i = 0;
foreach (byte c in a)
{
if (c != b[i])
return false;
i++;
}
return true;
}
#endregion
}
}
namespace SelfHelpPrintingSystemService.Common
{
////// 处理编码字符串或字符串
public static class EncodingStrOrByte
{
////// 编码方式
public enum EncodingType { UTF7, UTF8, UTF32, Unicode, BigEndianUnicode, ASCII, GB2312 };
////// 处理指定编码的字符串,转换字节数组
public static byte[] GetByte(string str, EncodingType encodingType)
{
byte[] bytes = null;
switch (encodingType)
{
//将要加密的字符串转换为指定编码的字节数组
case EncodingType.UTF7:
bytes = Encoding.UTF7.GetBytes(str);
break;
case EncodingType.UTF8:
bytes = Encoding.UTF8.GetBytes(str);
break;
case EncodingType.UTF32:
bytes = Encoding.UTF32.GetBytes(str);
break;
case EncodingType.Unicode:
bytes = Encoding.Unicode.GetBytes(str);
break;
case EncodingType.BigEndianUnicode:
bytes = Encoding.BigEndianUnicode.GetBytes(str);
break;
case EncodingType.ASCII:
bytes = Encoding.ASCII.GetBytes(str);
break;
case EncodingType.GB2312:
bytes = Encoding.Default.GetBytes(str);
break;
}
return bytes;
}
////// 处理指定编码的字节数组,转换字符串
public static string GetString(byte[] myByte, EncodingType encodingType)
{
string str = null;
switch (encodingType)
{
//将要加密的字符串转换为指定编码的字节数组
case EncodingType.UTF7:
str = Encoding.UTF7.GetString(myByte);
break;
case EncodingType.UTF8:
str = Encoding.UTF8.GetString(myByte);
break;
case EncodingType.UTF32:
str = Encoding.UTF32.GetString(myByte);
break;
case EncodingType.Unicode:
str = Encoding.Unicode.GetString(myByte);
break;
case EncodingType.BigEndianUnicode:
str = Encoding.BigEndianUnicode.GetString(myByte);
break;
case EncodingType.ASCII:
str = Encoding.ASCII.GetString(myByte);
break;
case EncodingType.GB2312:
str = Encoding.Default.GetString(myByte);
break;
}
return str;
}
}
}