191 lines
7.1 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
|