Forked from janierdavila/CoreUtilRSASignatureGenerator.cs
Last active
August 29, 2015 14:23
-
-
Save njmube/5e377ba2565ab1f7ed00 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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