Created
October 3, 2012 20:08
-
-
Save DevJohnC/3829524 to your computer and use it in GitHub Desktop.
Early RSA signing DTO
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.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()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I like it, might need to use something like this sometime, thx!