Kit.Core/LibCommon/Kit.Core.Helpers/Rsa/RSAService.cs

191 lines
7.1 KiB
C#

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;
}
}
}