using Masuit.Tools.Systems; using System; using System.Security.Cryptography; using System.Text; namespace Masuit.Tools.Security; /// /// RSA操作类 /// internal class RSA { /// /// 导出XML格式密钥对,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响 /// public string ToXML(bool convertToPublic = false) { return RSAObject.ToXmlString(!RSAObject.PublicOnly && !convertToPublic); } /// /// 导出PEM PKCS#1格式密钥对,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响 /// public string ToPEM_PKCS1(bool convertToPublic = false) { return new RsaPem(RSAObject).ToPEM(convertToPublic, false); } /// /// 导出PEM PKCS#8格式密钥对,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响 /// public string ToPEM_PKCS8(bool convertToPublic = false) { return new RsaPem(RSAObject).ToPEM(convertToPublic, true); } /// /// 将密钥对导出成PEM对象,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响 /// public RsaPem ToPEM(bool convertToPublic = false) { return new RsaPem(RSAObject, convertToPublic); } /// /// 加密字符串(utf-8),出错抛异常 /// public string Encrypt(string str) { return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(str))); } /// /// 加密数据,出错抛异常 /// public byte[] Encrypt(byte[] data) { int blockLen = RSAObject.KeySize / 8 - 11; if (data.Length <= blockLen) { return RSAObject.Encrypt(data, false); } using var dataStream = new PooledMemoryStream(data); using var enStream = new PooledMemoryStream(); var buffer = new byte[blockLen]; int len = dataStream.Read(buffer, 0, blockLen); while (len > 0) { var block = new byte[len]; Array.Copy(buffer, 0, block, 0, len); var enBlock = RSAObject.Encrypt(block, false); enStream.Write(enBlock, 0, enBlock.Length); len = dataStream.Read(buffer, 0, blockLen); } return enStream.ToArray(); } /// /// 解密字符串(utf-8),解密异常返回null /// public string DecryptOrNull(string str) { if (string.IsNullOrEmpty(str)) { return null; } try { var bytes = Convert.FromBase64String(str); var val = DecryptOrNull(bytes); return val == null ? null : Encoding.UTF8.GetString(val); } catch { return null; } } /// /// 解密数据,解密异常返回null /// public byte[] DecryptOrNull(byte[] data) { try { int blockLen = RSAObject.KeySize / 8; if (data.Length <= blockLen) { return RSAObject.Decrypt(data, false); } using var dataStream = new PooledMemoryStream(data); using var deStream = new PooledMemoryStream(); byte[] buffer = new byte[blockLen]; int len = dataStream.Read(buffer, 0, blockLen); while (len > 0) { var block = new byte[len]; Array.Copy(buffer, 0, block, 0, len); var deBlock = RSAObject.Decrypt(block, false); deStream.Write(deBlock, 0, deBlock.Length); len = dataStream.Read(buffer, 0, blockLen); } return deStream.ToArray(); } catch { return null; } } /// /// 对str进行签名,并指定hash算法(如:SHA256) /// public string Sign(string hash, string str) { return Convert.ToBase64String(Sign(hash, Encoding.UTF8.GetBytes(str))); } /// /// 对data进行签名,并指定hash算法(如:SHA256) /// public byte[] Sign(string hash, byte[] data) { return RSAObject.SignData(data, hash); } /// /// 验证字符串str的签名是否是sgin,并指定hash算法(如:SHA256) /// public bool Verify(string hash, string sgin, string str) { byte[] bytes = null; try { bytes = Convert.FromBase64String(sgin); } catch { } return bytes != null && Verify(hash, bytes, Encoding.UTF8.GetBytes(str)); } /// /// 验证data的签名是否是sgin,并指定hash算法(如:SHA256) /// public bool Verify(string hash, byte[] sgin, byte[] data) { try { return RSAObject.VerifyData(data, hash, sgin); } catch { return false; } } /// /// 最底层的RSACryptoServiceProvider对象 /// public RSACryptoServiceProvider RSAObject { get; } /// /// 密钥位数 /// public int KeySize => RSAObject.KeySize; /// /// 是否包含私钥 /// public bool HasPrivate => !RSAObject.PublicOnly; /// /// 用指定密钥大小创建一个新的RSA,出错抛异常 /// public RSA(int keySize) { RSAObject = new RSACryptoServiceProvider(keySize); } /// /// 通过公钥或私钥创建RSA,出错抛异常 /// public RSA(string key) { if (!key.StartsWith("<")) { RSAObject = RsaPem.FromPEM(key).GetRSA(); } else { RSAObject = new RSACryptoServiceProvider(); RSAObject.FromXmlString(key); } } /// /// 通过一个pem对象创建RSA,pem为公钥或私钥,出错抛异常 /// public RSA(RsaPem pem) { RSAObject = pem.GetRSA(); } }