using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Text; using System.Xml; namespace GBNewEnergy.Protocol.NEEncrypts { #if NETSTANDARD2_0 public class Default_NERSAEncryptImpl : NERSABase { private readonly RSA _privateKeyRsaProvider; private readonly RSA _publicKeyRsaProvider; private readonly Encoding _encoding; public override string HashAlgorithmStr=>throw new NotImplementedException(); public override string PublicKey { get; } public override string PrivateKey { get; } public override HashAlgorithmName HashAlgorithmName { get; } public Default_NERSAEncryptImpl(Encoding encoding, HashAlgorithmName hashAlgorithmName, string publicKey, string privateKey) { _privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey); _publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey); HashAlgorithmName = hashAlgorithmName; _encoding = encoding; PublicKey = publicKey; PrivateKey = privateKey; } public override byte[] Decrypt(byte[] buffer) { return _privateKeyRsaProvider.Decrypt(buffer, RSAEncryptionPadding.Pkcs1); } public override byte[] Encrypt(byte[] buffer) { return _publicKeyRsaProvider.Encrypt(buffer, RSAEncryptionPadding.Pkcs1); } /// /// 使用私钥签名 /// /// 原始数据 /// public override string Sign(string data) { byte[] dataBytes = _encoding.GetBytes(data); var signatureBytes = _privateKeyRsaProvider.SignData(dataBytes, HashAlgorithmName, RSASignaturePadding.Pkcs1); return Convert.ToBase64String(signatureBytes); } /// /// 使用公钥验证签名 /// /// 原始数据 /// 签名 /// public override bool Verify(string data, string sign) { byte[] dataBytes = _encoding.GetBytes(data); byte[] signBytes = Convert.FromBase64String(sign); var verify = _publicKeyRsaProvider.VerifyData(dataBytes, signBytes, HashAlgorithmName, RSASignaturePadding.Pkcs1); return verify; } private RSA CreateRsaProviderFromPublicKey(string publicKeyString) { var rsa = RSA.Create(); FromXmlStringExtensions(rsa,publicKeyString); return rsa; } private RSA CreateRsaProviderFromPrivateKey(string privateKey) { var rsa = RSA.Create(); FromXmlStringExtensions(rsa, privateKey); return rsa; } private int GetIntegerSize(BinaryReader binr) { byte bt = 0; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) return 0; bt = binr.ReadByte(); if (bt == 0x81) count = binr.ReadByte(); else if (bt == 0x82) { var highbyte = binr.ReadByte(); var 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 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; } private static void FromXmlStringExtensions(RSA rsa, string xmlString) { var parameters = new RSAParameters(); var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); if (xmlDoc.DocumentElement.Name.Equals("RSAKeyValue")) { foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes) { switch (node.Name) { case "Modulus": parameters.Modulus = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "Exponent": parameters.Exponent = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "P": parameters.P = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "Q": parameters.Q = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "DP": parameters.DP = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "DQ": parameters.DQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "InverseQ": parameters.InverseQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "D": parameters.D = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; } } } else { throw new Exception("Invalid XML RSA key."); } rsa.ImportParameters(parameters); } } #endif }