Last active
June 4, 2023 17:26
-
-
Save itsho/98bbb6d668b18072b6ffdf089ef28fc2 to your computer and use it in GitHub Desktop.
RSA - create signature and verify
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
// ---------------------------------------------------- | |
// Notice, this code is using BouncyCastle NuGet: | |
// https://www.nuget.org/packages/BouncyCastle/1.8.4/ | |
// Created by: Itsho | |
// Creation Date: 20 December 2018 | |
// ---------------------------------------------------- | |
using Org.BouncyCastle.Asn1.Pkcs; | |
using Org.BouncyCastle.Crypto; | |
using Org.BouncyCastle.Crypto.Generators; | |
using Org.BouncyCastle.Crypto.Parameters; | |
using Org.BouncyCastle.OpenSsl; | |
using Org.BouncyCastle.Security; | |
using System; | |
using System.IO; | |
using System.Text; | |
namespace Test | |
{ | |
public class Program | |
{ | |
[STAThread] | |
private static void Main(string[] args) | |
{ | |
// the 'usual' usage of keypair in "textbook" RSA (which is an asymmetric algorithm) is: | |
// public key = ENCRYPTING / VERIFYING | |
// private key = DECRYPTING / SIGNING | |
var rsav = new RsaSignAndVerify(); | |
var keyPair = rsav.GenerateRandomKeyPair(); | |
// print keys to console | |
rsav.PrintKeys(keyPair); | |
// content we like to sign | |
var textToSign = "Data to sign. can be a file or anything :-)"; | |
// display data we are about to sign | |
Console.WriteLine($"Text to sign: {textToSign}"); | |
// server side - generates the signature by using the PRIVATE key | |
var signature = rsav.ServerGenerateSignature(textToSign, (Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)keyPair.Private); | |
// client side - validates the signature by using the PUBLIC key | |
var isSignatureValid = rsav.ClientValidateSignature(textToSign, signature, (Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters) keyPair.Public); | |
Console.WriteLine($"Signature isValid: {isSignatureValid}"); | |
} | |
} | |
public class RsaSignAndVerify | |
{ | |
public AsymmetricCipherKeyPair GenerateRandomKeyPair() | |
{ | |
var rsaKeyPairGen = new RsaKeyPairGenerator(); | |
rsaKeyPairGen.Init(new KeyGenerationParameters(new SecureRandom(), 2048)); | |
return rsaKeyPairGen.GenerateKeyPair(); ; | |
} | |
public bool ClientValidateSignature(string sourceData, byte[] signature, RsaKeyParameters publicKey) | |
{ | |
byte[] tmpSource = Encoding.ASCII.GetBytes(sourceData); | |
ISigner signClientSide = SignerUtilities.GetSigner(PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id); | |
signClientSide.Init(false, publicKey); | |
signClientSide.BlockUpdate(tmpSource, 0, tmpSource.Length); | |
return signClientSide.VerifySignature(signature); | |
} | |
public byte[] ServerGenerateSignature(string sourceData, RsaKeyParameters privateKey) | |
{ | |
byte[] tmpSource = Encoding.ASCII.GetBytes(sourceData); | |
ISigner sign = SignerUtilities.GetSigner(PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id); | |
sign.Init(true, privateKey); | |
sign.BlockUpdate(tmpSource, 0, tmpSource.Length); | |
return sign.GenerateSignature(); | |
} | |
public void PrintKeys(AsymmetricCipherKeyPair keyPair) | |
{ | |
using (TextWriter textWriter1 = new StringWriter()) | |
{ | |
var pemWriter1 = new PemWriter(textWriter1); | |
pemWriter1.WriteObject(keyPair.Private); | |
pemWriter1.Writer.Flush(); | |
string privateKey = textWriter1.ToString(); | |
Console.WriteLine(privateKey); | |
} | |
using (TextWriter textWriter2 = new StringWriter()) | |
{ | |
var pemWriter2 = new PemWriter(textWriter2); | |
pemWriter2.WriteObject(keyPair.Public); | |
pemWriter2.Writer.Flush(); | |
string publicKey = textWriter2.ToString(); | |
Console.WriteLine(publicKey); | |
} | |
} | |
private byte[] ConvertHexString(string hexString) | |
{ | |
byte[] data = new byte[hexString.Length / 2]; | |
for (int index = 0; index < data.Length; index++) | |
{ | |
string byteValue = hexString.Substring(index * 2, 2); | |
data[index] = byte.Parse(byteValue, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture); | |
} | |
return data; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment