Skip to content

Instantly share code, notes, and snippets.

@DevJohnC
Created October 3, 2012 20:08
Show Gist options
  • Save DevJohnC/3829524 to your computer and use it in GitHub Desktop.
Save DevJohnC/3829524 to your computer and use it in GitHub Desktop.
Early RSA signing DTO
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using ServiceStack.Text;
namespace FragLabs.VOIP.Common.DTOs
{
/// <summary>
/// Base class for DTOs that must be securely signed using the RSA algorithm.
/// </summary>
abstract public class RSASigned
{
/// <summary>
/// RSA signature used to verify the author of the DTO.
/// </summary>
public byte[] Signature { get; set; }
/// <summary>
/// Nonce used to make sure no two requests are identical; avoids capturing packets and repeating them.
/// </summary>
public byte[] Nonce { get; set; }
/// <summary>
/// Request time in UTC. Makes signatures more unique and limits the viable timeframe for repeating captured packets.
/// </summary>
public DateTime UtcRequestTime { get; set; }
/// <summary>
/// Used to identify the sender of the message.
/// </summary>
public int SenderId { get; set; }
/// <summary>
/// Sign the request using the given provider.
/// </summary>
/// <param name="rsaSP"></param>
public void Sign(RSACryptoServiceProvider rsaSP)
{
Nonce = MakeNonce();
UtcRequestTime = DateTime.UtcNow;
var data = SignatureData();
Signature = rsaSP.SignData(data, new SHA512CryptoServiceProvider());
}
/// <summary>
/// Verify the sender of the message using the given provider.
/// </summary>
/// <param name="rsaSP"></param>
/// <returns></returns>
public bool Verify(RSACryptoServiceProvider rsaSP)
{
return rsaSP.VerifyData(SignatureData(), new SHA512CryptoServiceProvider(), Signature);
}
/// <summary>
/// Generates a cryptographically random nonce.
/// </summary>
/// <returns></returns>
protected byte[] MakeNonce()
{
return MakeNonce(8);
}
/// <summary>
/// Generates a cryptographically random nonce.
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
protected byte[] MakeNonce(int size)
{
var rng = new RNGCryptoServiceProvider();
var ret = new byte[size];
rng.GetBytes(ret);
return ret;
}
/// <summary>
/// Serializes the message and comverts to a byte array for signing.
/// </summary>
/// <returns></returns>
protected byte[] SignatureData()
{
byte[] storedSignature = default(byte[]);
if (Signature != default(byte[]))
{
storedSignature = Signature;
Signature = default(byte[]);
}
var serialization = JsonSerializer.SerializeToString(this, GetType());
if (storedSignature != default(byte[]))
Signature = storedSignature;
return System.Text.Encoding.UTF8.GetBytes(serialization.ToLower());
}
}
}
@mythz
Copy link

mythz commented Oct 3, 2012

I like it, might need to use something like this sometime, thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment