Skip to content

Instantly share code, notes, and snippets.

@rmbrunet
Last active May 10, 2016 16:25
Show Gist options
  • Save rmbrunet/b0036422202d0919698a6a872c5f7671 to your computer and use it in GitHub Desktop.
Save rmbrunet/b0036422202d0919698a6a872c5f7671 to your computer and use it in GitHub Desktop.
Generating and Validating Signed and Encrypted JTWs with Jose JWT (Linqpad).
// *********************************************
// Import nuget package Jose JWT
// https://github.com/dvsekhvalnov/jose-jwt
// ********************************************
void Main()
{
//Issuer Certificate
string i_certPath = @"path-to-issuer-certificate";
string i_password = "issuer-password";
//Consumer certificate
string c_certPath = @"path-to-consumer-certificate";
string c_password = "consumer-password";
// Creating the Token
X509Certificate2 i_cert = new X509Certificate2(i_certPath, i_password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
string tb = i_cert.Thumbprint;
byte[] bytes = new byte[tb.Length / 2];
for (int i = 0; i < tb.Length / 2; i++)
{
bytes[i] = byte.Parse(tb.Substring(2 * i, 2), System.Globalization.NumberStyles.HexNumber);
}
string x5t = Convert.ToBase64String(bytes).TrimEnd(new char[] { '=' }).Replace('+', '-').Replace('/', '_');
var payload = new Dictionary<string, object>
{
{"role", "user"},
{ "iss", "issuer"},
{ "aud", "audience"},
{ "exp", DateTimeOffset.UtcNow.AddDays(1).ToUnixTimeSeconds()},
{ "nbf", DateTimeOffset.UtcNow.ToUnixTimeSeconds()}
};
// Re-import the Key to avoid "Algorith not supported" error.
var i_privateKey = i_cert.PrivateKey as RSACryptoServiceProvider;
var i_publicKey = i_cert.PublicKey.Key as RSACryptoServiceProvider;
RSACryptoServiceProvider newKey = new RSACryptoServiceProvider();
newKey.ImportParameters(i_privateKey.ExportParameters(true));
//Sign the Token
string token = Jose.JWT.Encode(payload, newKey, JwsAlgorithm.RS256, new Dictionary<string, object> { { "typ", "JWT" }, { "x5t", x5t } });
token.Dump("Signed");
var newPayload = new Dictionary<string, object>
{
{"token", token}
};
// Encrypt using the Consumer public key.
X509Certificate2 c_cert = new X509Certificate2(c_certPath, c_password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
var c_publicKey = c_cert.PublicKey.Key as RSACryptoServiceProvider;
var c_privateKey = c_cert.PrivateKey as RSACryptoServiceProvider;
var enc_token = Jose.JWT.Encode(newPayload, c_publicKey, JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM, null, new Dictionary<string, object> { { "typ", "JWT" }, { "cty", "JWT" } });
enc_token.Dump("Encrypted");
// Verification
// Decrypt using the consumer private key
string received_token = Jose.JWT.Decode<Dictionary<string, string>>(enc_token, c_privateKey)["token"];
received_token.Dump("Decrypted");
// Validate the token signature using the issuer public key.
string final_token = Jose.JWT.Decode(received_token, i_publicKey);
final_token.Dump("Final");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment