namespace Kit.Helpers { using System; using System.Linq; using System.IO; using System.Security.Cryptography; using System.IO.Compression; public static class RSAService { public static byte[] RSAEncrypt(this byte[] dataToEncrypt, string privateKey, bool DoOAEPPadding = false) { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024)) { rsa.FromXmlString(privateKey); using (var fstreamOut = new MemoryStream()) { int i = 0; int sizebuf = 64; byte[] buf = new byte[sizebuf]; do { buf = dataToEncrypt.Skip(i * sizebuf).Take(sizebuf).ToArray(); if (buf.Length == 0) break; byte[] encrypted = rsa.Encrypt(buf, DoOAEPPadding); fstreamOut.Write(encrypted, 0, encrypted.Length); i++; } while (buf.Length == sizebuf); fstreamOut.Position = 0; return fstreamOut.ReadAllBytes(); } } } public static byte[] RSADecrypt(this byte[] dataToDecrypt, string publickey, bool DoOAEPPadding = false) { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024)) { rsa.FromXmlString(publickey); using (var fstreamOut = new MemoryStream()) { int i = 0; int sizebuf = 128; byte[] buf = new byte[sizebuf]; do { buf = dataToDecrypt.Skip(i * sizebuf).Take(sizebuf).ToArray(); if (buf.Length == 0) break; byte[] encrypted = rsa.Decrypt(buf, DoOAEPPadding); fstreamOut.Write(encrypted, 0, encrypted.Length); i++; } while (buf.Length == sizebuf); fstreamOut.Position = 0; return fstreamOut.ReadAllBytes(); } } } public static byte[] RSAGetSignature(this byte[] data, string privedkey) { using (RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider()) { rsaCSP.FromXmlString(privedkey); SHA256Managed hash = new SHA256Managed(); byte[] hashedData; hashedData = hash.ComputeHash(data); return rsaCSP.SignHash(hashedData, CryptoConfig.MapNameToOID("SHA256")); } } public static bool RSAVerifySignature(this byte[] signedData, string publickey, byte[] signature) { using (RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider()) { rsaCSP.FromXmlString(publickey); SHA256Managed hash = new SHA256Managed(); byte[] hashedData; bool dataOK = rsaCSP.VerifyData(signedData, CryptoConfig.MapNameToOID("SHA256"), signature); hashedData = hash.ComputeHash(signedData); return rsaCSP.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA256"), signature); } } public static Stream GetPackedSignature(this Stream stream, string privedkey) { return stream.ReadAllBytes().GetPackedSignature(privedkey); } public static Stream GetPackedSignature(this byte[] data, string privedkey) { byte[] signature = data.RSAGetSignature(privedkey); Stream packed = new MemoryStream(); using (var zipObj = new ZipArchive(packed, ZipArchiveMode.Create,true)) { ZipArchiveEntry entryData = zipObj.CreateEntry("file.dat"); using (var entryStream = entryData.Open()) { entryStream.Write(data, 0, data.Length); entryStream.Flush(); } ZipArchiveEntry entrySignature = zipObj.CreateEntry("signature.key"); using (var entryStream = entrySignature.Open()) { entryStream.Write(signature, 0, signature.Length); entryStream.Flush(); } } return packed; } public static bool VerifyPackedSignature(this byte[] arhiveData, string publickey) { using (ZipArchive archive = new ZipArchive(new MemoryStream(arhiveData), ZipArchiveMode.Read)) { //если нет файла подписи и файла данных (нарушен формат пакета) то проверка отрицательная if ( !archive.Entries.Any(x => x.FullName.EndsWith("signature.key")) || !archive.Entries.Any(x => x.FullName.EndsWith("file.dat")) ) return false; byte[] signature = new byte[] { }; byte[] data = new byte[] { }; foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName.EndsWith("signature.key", StringComparison.OrdinalIgnoreCase)) { signature = entry.Open().ReadAllBytes(); } if (entry.FullName.EndsWith("file.dat", StringComparison.OrdinalIgnoreCase)) { data = entry.Open().ReadAllBytes(); } } if (signature.Length == 0 || data.Length == 0) return false; return RSAVerifySignature(data, publickey, signature); } } public static byte[] ReadPackedWithSignature(this byte[] arhiveData, string publickey) { return new MemoryStream(arhiveData).ReadPackedWithSignature(publickey); } public static byte[] ReadPackedWithSignature(this Stream arhiveStream, string publickey) { using (ZipArchive archive = new ZipArchive(arhiveStream, ZipArchiveMode.Read)) { byte[] signature = new byte[] { }; byte[] data = new byte[] { }; foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName.EndsWith("signature.key", StringComparison.OrdinalIgnoreCase)) { signature = entry.Open().ReadAllBytes(); } if (entry.FullName.EndsWith("file.dat", StringComparison.OrdinalIgnoreCase)) { data = entry.Open().ReadAllBytes(); } } if (signature.Length == 0 || data.Length == 0) return null; if(RSAVerifySignature(data, publickey, signature)) { return data; } } return null; } } }