242 lines
7.4 KiB
C#
242 lines
7.4 KiB
C#
using System;
|
||
using System.Security.Cryptography;
|
||
using System.Text;
|
||
|
||
/*
|
||
RSA rSA = new RSA();
|
||
//公钥
|
||
string pubkey = rSA.ToPEM_PKCS1(true);
|
||
//私钥
|
||
string priKey = rSA.ToPEM_PKCS1();
|
||
//公钥加密
|
||
RSA rrSA = new RSA(pubkey, true);
|
||
string abc123=rrSA.Encode("abc123");
|
||
---------------------------------------------------------------------------------
|
||
前端公钥加密
|
||
let encrypt = new JSEncrypt();
|
||
encrypt.setPublicKey(pubkey);
|
||
data.RsaUserPassword = encrypt
|
||
.encrypt(data.UserPassword + CryptoJS.MD5(state.LoginData.UserPassword))
|
||
.toString();
|
||
---------------------------------------------------------------------------------
|
||
//私钥解密
|
||
rrSA = new RSA(priKey, true);
|
||
string desc = rrSA.DecodeOrNull(abc123);
|
||
*/
|
||
namespace System
|
||
{
|
||
/// <summary>
|
||
/// RSA操作类
|
||
/// </summary>
|
||
public class RSA
|
||
{
|
||
/// <summary>
|
||
/// 导出XML格式密钥对,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
|
||
/// </summary>
|
||
public string ToXML(bool convertToPublic = false)
|
||
{
|
||
return rsa.ToXmlString(!rsa.PublicOnly && !convertToPublic);
|
||
}
|
||
/// <summary>
|
||
/// 导出PEM PKCS#1格式密钥对,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
|
||
/// </summary>
|
||
public string ToPEM_PKCS1(bool convertToPublic = false)
|
||
{
|
||
return RSA_PEM.ToPEM(rsa, convertToPublic, false);
|
||
}
|
||
/// <summary>
|
||
/// 导出PEM PKCS#8格式密钥对,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
|
||
/// </summary>
|
||
public string ToPEM_PKCS8(bool convertToPublic = false)
|
||
{
|
||
return RSA_PEM.ToPEM(rsa, convertToPublic, true);
|
||
}
|
||
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 加密字符串(utf-8),出错抛异常
|
||
/// </summary>
|
||
public string Encode(string str)
|
||
{
|
||
return RSA_Unit.Base64EncodeBytes(Encode(Encoding.UTF8.GetBytes(str)));
|
||
}
|
||
/// <summary>
|
||
/// 加密数据,出错抛异常
|
||
/// </summary>
|
||
public byte[] Encode(byte[] data)
|
||
{
|
||
int blockLen = rsa.KeySize / 8 - 11;
|
||
if (data.Length <= blockLen)
|
||
{
|
||
return rsa.Encrypt(data, false);
|
||
}
|
||
|
||
using (var dataStream = new MemoryStream(data))
|
||
using (var enStream = new MemoryStream())
|
||
{
|
||
Byte[] buffer = new Byte[blockLen];
|
||
int len = dataStream.Read(buffer, 0, blockLen);
|
||
|
||
while (len > 0)
|
||
{
|
||
Byte[] block = new Byte[len];
|
||
Array.Copy(buffer, 0, block, 0, len);
|
||
|
||
Byte[] enBlock = rsa.Encrypt(block, false);
|
||
enStream.Write(enBlock, 0, enBlock.Length);
|
||
|
||
len = dataStream.Read(buffer, 0, blockLen);
|
||
}
|
||
|
||
return enStream.ToArray();
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 解密字符串(utf-8),解密异常返回null
|
||
/// </summary>
|
||
public string DecodeOrNull(string str)
|
||
{
|
||
if (String.IsNullOrEmpty(str))
|
||
{
|
||
return null;
|
||
}
|
||
var byts = RSA_Unit.Base64DecodeBytes(str);
|
||
if (byts == null)
|
||
{
|
||
return null;
|
||
}
|
||
var val = DecodeOrNull(byts);
|
||
if (val == null)
|
||
{
|
||
return null;
|
||
}
|
||
return Encoding.UTF8.GetString(val);
|
||
}
|
||
/// <summary>
|
||
/// 解密数据,解密异常返回null
|
||
/// </summary>
|
||
public byte[] DecodeOrNull(byte[] data)
|
||
{
|
||
try
|
||
{
|
||
int blockLen = rsa.KeySize / 8;
|
||
if (data.Length <= blockLen)
|
||
{
|
||
return rsa.Decrypt(data, false);
|
||
}
|
||
|
||
using (var dataStream = new MemoryStream(data))
|
||
using (var deStream = new MemoryStream())
|
||
{
|
||
Byte[] buffer = new Byte[blockLen];
|
||
int len = dataStream.Read(buffer, 0, blockLen);
|
||
|
||
while (len > 0)
|
||
{
|
||
Byte[] block = new Byte[len];
|
||
Array.Copy(buffer, 0, block, 0, len);
|
||
|
||
Byte[] deBlock = rsa.Decrypt(block, false);
|
||
deStream.Write(deBlock, 0, deBlock.Length);
|
||
|
||
len = dataStream.Read(buffer, 0, blockLen);
|
||
}
|
||
|
||
return deStream.ToArray();
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 对str进行签名,并指定hash算法(如:SHA256)
|
||
/// </summary>
|
||
public string Sign(string hash, string str)
|
||
{
|
||
return RSA_Unit.Base64EncodeBytes(Sign(hash, Encoding.UTF8.GetBytes(str)));
|
||
}
|
||
/// <summary>
|
||
/// 对data进行签名,并指定hash算法(如:SHA256)
|
||
/// </summary>
|
||
public byte[] Sign(string hash, byte[] data)
|
||
{
|
||
return rsa.SignData(data, hash);
|
||
}
|
||
/// <summary>
|
||
/// 验证字符串str的签名是否是sgin,并指定hash算法(如:SHA256)
|
||
/// </summary>
|
||
public bool Verify(string hash, string sgin, string str)
|
||
{
|
||
var byts = RSA_Unit.Base64DecodeBytes(sgin);
|
||
if (byts == null)
|
||
{
|
||
return false;
|
||
}
|
||
return Verify(hash, byts, Encoding.UTF8.GetBytes(str));
|
||
}
|
||
/// <summary>
|
||
/// 验证data的签名是否是sgin,并指定hash算法(如:SHA256)
|
||
/// </summary>
|
||
public bool Verify(string hash, byte[] sgin, byte[] data)
|
||
{
|
||
try
|
||
{
|
||
return rsa.VerifyData(data, hash, sgin);
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
private RSACryptoServiceProvider rsa;
|
||
private void _init()
|
||
{
|
||
var rsaParams = new CspParameters();
|
||
rsaParams.Flags = CspProviderFlags.UseMachineKeyStore;
|
||
rsa = new RSACryptoServiceProvider(rsaParams);
|
||
}
|
||
public RSA() : this(2048)
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 用指定密钥大小创建一个新的RSA,出错抛异常
|
||
/// </summary>
|
||
public RSA(int keySize)
|
||
{
|
||
_init();
|
||
|
||
var rsaParams = new CspParameters();
|
||
rsaParams.Flags = CspProviderFlags.UseMachineKeyStore;
|
||
rsa = new RSACryptoServiceProvider(keySize, rsaParams);
|
||
}
|
||
/// <summary>
|
||
/// 通过指定的密钥,创建一个RSA,xml内可以只包含一个公钥或私钥,或都包含,出错抛异常
|
||
/// </summary>
|
||
public RSA(string xml)
|
||
{
|
||
_init();
|
||
|
||
rsa.FromXmlString(xml);
|
||
}
|
||
/// <summary>
|
||
/// 通过一个pem文件创建RSA,pem为公钥或私钥,出错抛异常
|
||
/// </summary>
|
||
public RSA(string pem, bool noop)
|
||
{
|
||
_init();
|
||
|
||
rsa = RSA_PEM.FromPEM(pem);
|
||
}
|
||
}
|
||
}
|