Skip to content

Instantly share code, notes, and snippets.

@apotox
Created January 23, 2020 14:01
Show Gist options
  • Save apotox/4ecadd7aa1f274bd7a886f254cb1a114 to your computer and use it in GitHub Desktop.
Save apotox/4ecadd7aa1f274bd7a886f254cb1a114 to your computer and use it in GitHub Desktop.
RSA signature sample code without RSACryptoServiceProvider
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
using System.Security.Cryptography;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Globalization;
//RSA signature sample example
namespace RSASIGNATURE
{
public class RSASIGNATURE
{
public BigInteger e, p, q, n, phi;
private BigInteger Encrypt(BigInteger m, BigInteger e, BigInteger n) //encryption
{
return BigInteger.ModPow(m, e, n);
}
private BigInteger Decrypt(BigInteger cResult, BigInteger d, BigInteger n) //decryption
{
return BigInteger.ModPow(cResult, d, n);
}
private void generateParams(string p_str, string q_str)
{
p = BigInteger.Parse(p_str);
q = BigInteger.Parse(q_str);
e = BigInteger.Parse("65537");
n = p * q;
phi = (p - 1) * (q - 1);
}
private Tuple<BigInteger, BigInteger, BigInteger> generatePrivateKey()
{
return egcd(e, phi);
}
Tuple<BigInteger, BigInteger, BigInteger> egcd(BigInteger a, BigInteger b)
{
BigInteger x = 0, y = 1, u = 1, v = 0, gcd = 0;
while (a != 0)
{
q = b / a;
BigInteger r = b % a;
BigInteger m = x - u * q;
BigInteger n = y - v * q;
b = a;
a = r;
x = u;
y = v;
u = m;
v = n;
gcd = b;
}
if (x < 0) x += phi;
if (y < 0) y += phi;
return Tuple.Create(gcd, x, y);
}
public string Sign(string message, string privatekey)
{
string hash = CalculateMD5Hash(message);
var pr_object = JObject.Parse(GZIP.DecompressString(privatekey));
var big = BigInteger.Parse(hash, NumberStyles.HexNumber); //new BigInteger(Encoding.ASCII.GetBytes(hash));
var signature = this.Encrypt(big, BigInteger.Parse(pr_object.GetValue("d").ToString()), BigInteger.Parse(pr_object.GetValue("n").ToString())); // to hex
return signature.ToString("X");
}
public string[] encodeKeys()
{
var gcd_d_y = this.generatePrivateKey();
var pk = new
{
n = this.n,
e = this.e
};
var pr = new
{
n = this.n,
d = gcd_d_y.Item2
};
return new String[] { GZIP.CompressString(JsonConvert.SerializeObject(pk)), GZIP.CompressString(JsonConvert.SerializeObject(pr)) };
}
public JObject[] decodeKeys(string pk, string pr)
{
var pk_object = JObject.Parse(GZIP.DecompressString(pk));
var pr_object = JObject.Parse(GZIP.DecompressString(pr));
return new JObject[] { pk_object, pr_object };
}
public bool Verify(string message, string publickey, string signature)
{
var pk_object = JObject.Parse(GZIP.DecompressString(publickey));
string hash = this.CalculateMD5Hash(message);
var signatureBig = BigInteger.Parse(signature, NumberStyles.HexNumber);
var dec = this.Decrypt(signatureBig, BigInteger.Parse(pk_object.GetValue("e").ToString()), BigInteger.Parse(pk_object.GetValue("n").ToString()));
return dec.ToString("X") == hash;
}
public string CalculateMD5Hash(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
}
}
//main.cs
RSASIGNATURE rsa = new RSASIGNATURE();
// p , q params
BigInteger p = "1090660992520643446103273789680343";
BigInteger q = "1162435056374824133712043309728653";
rsa.generateParams(p, q);
//encode private and public keys
string[] keyspair = rsa.encodeKeys();
Console.WriteLine("Public key: "+ keyspair[0]); //<e,n>
Console.WriteLine("Private key: "+ keyspair[1]); //<d,n>
string message = "by safi";
//generate signature
string signature = rsa.Sign(message,keyspair[1]);
Console.WriteLine("Signature: "+ signature);
//verify signature
bool verfied = rsa.Verify(message,keyspair[0],signature)
Assert.isTrue(verfied);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment