Skip to content

Instantly share code, notes, and snippets.

@maximilian-krauss
Last active December 19, 2015 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maximilian-krauss/5984278 to your computer and use it in GitHub Desktop.
Save maximilian-krauss/5984278 to your computer and use it in GitHub Desktop.
Basic provider to sign a json document using the dsa algorithm
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization;
// Add reference to System.Runtime.Serialization.dll
namespace kraussIO {
public class Message {
public string Id { get; set; }
public string From { get; set; }
public string To { get; set; }
public string Content { get; set; }
}
class Program {
static void Main(string[] args) {
var dsa = DSACryptoServiceProvider.Create();
dsa.KeySize = 1024;
var p = dsa.ExportParameters(true);
var m = new Message {
Id = Guid.NewGuid().ToString(),
From = "Mr. X",
To = "Mr. Y",
Content = "Secret 123"
};
var s = new SignedJson<Message>(p) {
Graph = m
};
s.Sign();
var transferredContent = s.SignedEnvelope;
s = null;
m = null;
//Test (uncomment and the validation will fail)
//transferredContent = transferredContent.Replace("Mr. X", "Mr. B");
var pbk = dsa.ExportParameters(false);
var sPbk = new SignedJson<Message>(pbk);
var valid = sPbk.ValidateSignature(transferredContent);
}
}
[DataContract]
public sealed class SignedJsonEnvelope {
[DataMember(Name = "serializedGraph")]
public string SerializedGraph { get; set; }
[DataMember(Name = "publicKey")]
public string PublicKey { get; set; }
[DataMember(Name = "signature")]
public string Signature { get; set; }
public byte[] GetHashedContent() {
return SHA1.Create().ComputeHash(
Encoding.UTF8.GetBytes(SerializedGraph + PublicKey)
);
}
}
public class SignedJson<T> where T : class {
private readonly DSACryptoServiceProvider _DSA;
public SignedJson(DSAParameters dsaParameters) {
_DSA = (DSACryptoServiceProvider)DSACryptoServiceProvider.Create();
_DSA.ImportParameters(dsaParameters);
}
public SignedJson(string dsaParameterXmlString) {
_DSA = (DSACryptoServiceProvider)DSACryptoServiceProvider.Create();
_DSA.FromXmlString(dsaParameterXmlString);
}
public T Graph { get; set; }
public string SignedEnvelope { get; private set; }
public void Sign() {
var envelope = new SignedJsonEnvelope {
PublicKey = _DSA.ToXmlString(false),
SerializedGraph = ToJson<T>(Graph)
};
envelope.Signature = Convert.ToBase64String(_DSA.CreateSignature(envelope.GetHashedContent()));
SignedEnvelope = ToJson<SignedJsonEnvelope>(envelope);
}
public bool ValidateSignature(string signedEnvelope) {
var envelope = FromJson<SignedJsonEnvelope>(signedEnvelope);
if (_DSA.VerifySignature(envelope.GetHashedContent(), Convert.FromBase64String(envelope.Signature))) {
Graph = (T)FromJson<T>(envelope.SerializedGraph);
SignedEnvelope = signedEnvelope;
return true;
}
return false;
}
private string ToJson<T>(T graph) {
using (var memoryStream = new MemoryStream()) {
var jsonSerializer = new DataContractJsonSerializer(typeof(T));
jsonSerializer.WriteObject(memoryStream, graph);
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
}
private T FromJson<T>(string json) {
using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(json))) {
var jsonSerializer = new DataContractJsonSerializer(typeof(T));
return (T)jsonSerializer.ReadObject(memoryStream);
}
}
private byte[] ToSha1(string input) {
var sha = SHA1.Create();
return sha.ComputeHash(Encoding.UTF8.GetBytes(input));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment