Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save njmube/5e377ba2565ab1f7ed00 to your computer and use it in GitHub Desktop.
Save njmube/5e377ba2565ab1f7ed00 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Globalization;
using System.Text;
namespace Core.Util
{
/// <summary>
/// Signs a byte array with a RSA signature. And Generates private & public keys.
/// </summary>
public class RSASignatureGenerator
{
static RSACryptoServiceProvider cryptoProvider = new RSACryptoServiceProvider();
static AsymmetricSignatureFormatter formatter = new RSAPKCS1SignatureFormatter();
static AsymmetricSignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter();
public void WritePrivateKeyToFile(RSAParameters param, string fileName)
{
FileStream sw = File.Create(fileName);
WriteByteArray(sw, param.P);
WriteByteArray(sw, param.Q);
WriteByteArray(sw, param.D);
WriteByteArray(sw, param.DP);
WriteByteArray(sw, param.DQ);
WriteByteArray(sw, param.InverseQ);
WriteByteArray(sw, param.Exponent);
WriteByteArray(sw, param.Modulus);
sw.Close();
}
public RSAParameters ReadPrivateKeyFromFile(string fileName)
{
RSAParameters param = new RSAParameters();
FileStream sw = File.OpenRead(fileName);
param.P = ReadByteArray(sw);
param.Q = ReadByteArray(sw);
param.D = ReadByteArray(sw);
param.DP = ReadByteArray(sw);
param.DQ = ReadByteArray(sw);
param.InverseQ = ReadByteArray(sw);
param.Exponent = ReadByteArray(sw);
param.Modulus = ReadByteArray(sw);
sw.Close();
return param;
}
public void WritePublicKeyToFile(RSAParameters param, string fileName)
{
FileStream sw = File.Create(fileName);
WriteByteArray(sw, param.Exponent);
WriteByteArray(sw, param.Modulus);
sw.Close();
}
public RSAParameters ReadPublicKeyFromFile(string fileName)
{
RSAParameters param = new RSAParameters();
FileStream sw = File.OpenRead(fileName);
param.Exponent = ReadByteArray(sw);
param.Modulus = ReadByteArray(sw);
sw.Close();
return param;
}
/// <summary>
/// Returns a new generated <code>RSAParameters</code> class which
/// will be used as a key for the signature.
/// Note : It will generate a PRIVATE key (which includes the PUBLIC
/// key)
/// </summary>
public RSAParameters GenerateNewRSAParameters()
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
return provider.ExportParameters(true);
}
byte[] GenerateMD5Hash(byte[] data)
{
HashAlgorithm hash = new MD5CryptoServiceProvider();
return hash.ComputeHash(data);
}
public byte[] SignData(byte[] data, RSAParameters privateKey)
{
byte[] hashCode = GenerateMD5Hash(data);
formatter.SetHashAlgorithm("MD5");
cryptoProvider.ImportParameters(privateKey);
formatter.SetKey(cryptoProvider);
return formatter.CreateSignature(hashCode);
}
public bool VerifySignature(byte[] data, byte[] signature, RSAParameters publicKey)
{
byte[] hashCode = GenerateMD5Hash(data);
cryptoProvider.ImportParameters(publicKey);
deformatter.SetHashAlgorithm("MD5");
deformatter.SetKey(cryptoProvider);
return deformatter.VerifySignature(hashCode, signature);
}
public string GetStringFromArray(byte[] array)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.Length; ++i)
{
string s = String.Format("{0:X}", array[i]);
if (s.Length == 1)
{
s = '0' + s;
}
sb.Append(s);
}
return sb.ToString();
}
public byte[] GetArrayFromString(string str, int offset, int length)
{
byte[] array = new byte[length];
for (int i = 0; i < length; ++i)
{
array[i] = Byte.Parse(str.Substring(offset + i * 2, 2), NumberStyles.HexNumber);
}
return array;
}
public string GetPublicKeyString(RSAParameters p)
{
return GetStringFromArray(p.Exponent) + GetStringFromArray(p.Modulus);
}
public RSAParameters GetPublicKey(string key)
{
RSAParameters p = new RSAParameters();
p.Exponent = GetArrayFromString(key, 0, 3);
p.Modulus = GetArrayFromString(key, 3 * 2, 128);
return p;
}
public byte[] ReadSignature(string fileName)
{
StreamReader sr = File.OpenText(fileName);
string key = sr.ReadLine();
sr.Close();
return GetArrayFromString(key, 0, 128);
}
void WriteByteArray(FileStream writer, byte[] array)
{
if (array == null || array.Length == 0)
{
for (int i = 0; i < 4; ++i)
{
writer.WriteByte(0);
}
return;
}
int length = array.Length;
for (int i = 0; i < 4; ++i)
{
writer.WriteByte((byte)((length & (0xFF << (8 * i))) >> (8 * i)));
}
writer.Write(array, 0, array.Length);
}
byte[] ReadByteArray(FileStream writer)
{
int length = 0;
for (int i = 0; i < 4; ++i)
{
length = length | writer.ReadByte() >> (8 * (32 - 8 - i));
}
if (length == 0)
{
return null;
}
byte[] array = new byte[length];
writer.Read(array, 0, length);
return array;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment