Last active
May 10, 2016 16:25
-
-
Save rmbrunet/b0036422202d0919698a6a872c5f7671 to your computer and use it in GitHub Desktop.
Generating and Validating Signed and Encrypted JTWs with Jose JWT (Linqpad).
This file contains 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
// ********************************************* | |
// 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