Skip to content

Instantly share code, notes, and snippets.

@opentechnologist
Created September 22, 2025 21:31
Show Gist options
  • Save opentechnologist/312fd9e79e371e1bc3904629b7a42036 to your computer and use it in GitHub Desktop.
Save opentechnologist/312fd9e79e371e1bc3904629b7a42036 to your computer and use it in GitHub Desktop.
a simple implementation of file tamper detection in c# using rsa cryptographic functions.
using System;
using RsaFileCrypto; // RsaXmlKeyHelper, RsaFileHelper, HybridFileCryptoHelper
namespace MainPackage
{
class MainClass
{
static void Main(string[] args)
{
// generate and save key pair
RsaXmlKeyHelper keyHelper = new RsaXmlKeyHelper();
// 256-bit key pair, possible values 512, 1024, 2048, 4096, higher is more secure
keyHelper.GenerateKeyPair(256);
keyHelper.SaveKeyPair("keypair");
}
}
}
using System.IO;
using System.Security.Cryptography;
namespace RsaFileCrypto
{
public class RsaFileHelper
{
// Signs a file using a private key (XML format), using a byte array
public void SignFile(string inputFile, string signatureFile, string privateKeyXml)
{
RsaXmlKeyHelper keyHelper = new RsaXmlKeyHelper();
var rsa = keyHelper.ImportKey(privateKeyXml);
byte[] data = File.ReadAllBytes(inputFile);
byte[] signature = rsa.SignData(data, "SHA256");
File.WriteAllBytes(signatureFile, signature);
}
// Verifies the signature of a file using a public key (XML format), using a byte array
public bool VerifyFile(string inputFile, string signatureFile, string publicKeyXml)
{
RsaXmlKeyHelper keyHelper = new RsaXmlKeyHelper();
var rsa = keyHelper.ImportKey(publicKeyXml);
byte[] data = File.ReadAllBytes(inputFile);
byte[] signature = File.ReadAllBytes(signatureFile);
return rsa.VerifyData(data, "SHA256", signature);
}
}
}
using System;
using System.Security.Cryptography;
using System.IO;
namespace RsaFileCrypto
{
public class RsaXmlKeyHelper
{
private RSACryptoServiceProvider keyPair;
public RSACryptoServiceProvider KeyPair
{
get { return keyPair; }
set { keyPair = value; }
}
public RSACryptoServiceProvider GenerateKeyPair(int keySize)
{
keyPair = new RSACryptoServiceProvider(keySize);
return keyPair;
}
public string ExportPublicKey()
{
if (keyPair == null)
throw new InvalidOperationException("No key generated.");
return keyPair.ToXmlString(false); // public key only
}
public string ExportPrivateKey()
{
if (keyPair == null)
throw new InvalidOperationException("No key generated.");
return keyPair.ToXmlString(true); // private and public key pair
}
public RSACryptoServiceProvider ImportKey(string xmlKey)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(xmlKey);
keyPair = rsa;
return keyPair;
}
public RSACryptoServiceProvider LoadPublicKey(string filePath)
{
return LoadKeyFile(string.Format("{0}_publicKey.xml", filePath));
}
public RSACryptoServiceProvider LoadPrivateKey(string filePath)
{
return LoadKeyFile(string.Format("{0}_privateKey.xml", filePath));
}
private RSACryptoServiceProvider LoadKeyFile(string keyPath)
{
if (!File.Exists(keyPath))
throw new FileNotFoundException("Key file not found.", keyPath);
string keyText = File.ReadAllText(keyPath);
ImportKey(keyText);
if (keyPair == null)
throw new InvalidOperationException("Error loading key file.");
return keyPair;
}
public void SaveKeyPair(string pathPrefix)
{
if (keyPair == null)
throw new InvalidOperationException("No key generated.");
string publicKeyPath = string.Format("{0}_publicKey.xml", pathPrefix) ;
string privateKeyPath = string.Format("{0}_privateKey.xml", pathPrefix);
try
{
string publicKeyText = ExportPublicKey();
File.WriteAllText(publicKeyPath, ExportPublicKey()); // Save public key
string privateKeyText = ExportPrivateKey();
if (privateKeyText != publicKeyText) // check if only public key is loaded
File.WriteAllText(privateKeyPath, ExportPrivateKey()); // Save private and public key pair
}
catch (Exception ex)
{
throw new IOException("Error saving keys.", ex);
}
}
}
}
using System;
using System.IO;
using RsaFileCrypto; // RsaXmlKeyHelper, RsaFileHelper, HybridFileCryptoHelper
namespace MainPackage
{
class MainClass
{
static void Main(string[] args)
{
try
{
// load public and private key pair file
RsaXmlKeyHelper keyHelper = new RsaXmlKeyHelper();
keyHelper.LoadPrivateKey("keypair"); // prefix name, it could be any name
Console.WriteLine("Private Key: {0}", keyHelper.ExportPrivateKey());
}
catch (Exception ex)
{
throw new IOException("Error loading key.", ex);
}
}
}
}
using System;
using System.IO;
using RsaFileCrypto; // RsaXmlKeyHelper, RsaFileHelper, HybridFileCryptoHelper
namespace MainPackage
{
class MainClass
{
static void Main(string[] args)
{
try
{
// load public key file
RsaXmlKeyHelper keyHelper = new RsaXmlKeyHelper();
keyHelper.LoadPublicKey("keypair"); // prefix name, it could be any name
Console.WriteLine("Public Key: {0}", keyHelper.ExportPublicKey());
}
catch (Exception ex)
{
throw new IOException("Error loading key.", ex);
}
}
}
}
using System;
using System.IO;
using RsaFileCrypto; // RsaXmlKeyHelper, RsaFileHelper, HybridFileCryptoHelper
namespace MainPackage
{
class MainClass
{
static void Main(string[] args)
{
try
{
// sign text file using private key
RsaXmlKeyHelper keyHelper = new RsaXmlKeyHelper();
keyHelper.LoadPrivateKey("keypair");
// sign the file
RsaFileHelper fileHelper = new RsaFileHelper();
var inputFile = "input.txt";
if (File.Exists(inputFile))
{
Console.WriteLine("Signing file: {0}", inputFile);
var signatureFile = string.Format("{0}.sig", inputFile);
fileHelper.SignFile(inputFile, signatureFile, keyHelper.ExportPrivateKey());
Console.WriteLine("File signed successfully.");
}
}
catch (Exception ex)
{
throw new IOException("Error loading key pair or signing file.", ex);
}
}
}
}
using System;
using System.IO;
using RsaFileCrypto; // RsaXmlKeyHelper, RsaFileHelper, HybridFileCryptoHelper
namespace MainPackage
{
class MainClass
{
static void Main(string[] args)
{
try
{
// verify file signature using public key
RsaXmlKeyHelper keyHelper = new RsaXmlKeyHelper();
keyHelper.LoadPublicKey("keypair");
// verify signature
RsaFileHelper fileHelper = new RsaFileHelper();
var inputFile = "input.txt";
var signatureFile = string.Format("{0}.sig", inputFile);
if (File.Exists(inputFile) && File.Exists(signatureFile))
{
Console.WriteLine("Verifying signature: {0}", inputFile);
bool isValid = fileHelper.VerifyFile(inputFile, signatureFile, keyHelper.ExportPublicKey());
if (isValid)
Console.WriteLine("Signature is valid. File is authentic.");
else
Console.WriteLine("Signature is invalid. File was tampered!");
}
}
catch (Exception ex)
{
throw new IOException("Error loading key pair or signing file.", ex);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment