public void WrongCertificateThrowsError() { var options = new ECCertificateBuilderOptions { ECCurve = ECNamedCurves.P256, FullSubjectName = "CN=Test" }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); string headerJson; var token = JsonWebToken.EncodeUsingECDSA(new {id = 1, org = 2}, cert, out headerJson); options = new ECCertificateBuilderOptions { ECCurve = ECNamedCurves.P256, FullSubjectName = "CN=Test" }; cert = ECCertificateBuilder.CreateNewSigningCertificate(options); try { string payloadJson; JsonWebToken.DecodeUsingECDSA<object>(token, cert, out headerJson, out payloadJson); } catch (SignatureVerificationException ex) { Assert.AreEqual("Token does not match signature", ex.Message); return; } Assert.Fail(); }
public void ParseBackAndForthWorks() { var options = new ECCertificateBuilderOptions { ECCurve = ECNamedCurves.P256, FullSubjectName = "CN=Test" }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); string headerJson; var token = JsonWebToken.EncodeUsingECDSA(new {id = 1, org = 2}, cert, out headerJson); string headerJsonDecoded; string payloadJsonDecoded; dynamic result = JsonWebToken.DecodeUsingECDSA<object>(token, cert, out headerJsonDecoded, out payloadJsonDecoded); Assert.AreEqual(1, (int)result.id); Assert.AreEqual(2, (int)result.org); Assert.IsFalse(string.IsNullOrWhiteSpace(headerJsonDecoded)); Assert.IsTrue(string.Equals(headerJson, headerJsonDecoded)); Assert.IsFalse(string.IsNullOrWhiteSpace(payloadJsonDecoded)); }
public void CreateWithSha384Hash() { var options = new ECCertificateBuilderOptions { FullSubjectName = "CN=Test", HashingMethod = HashingMethods.Sha384 }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); Assert.AreEqual("CN=Test", cert.Subject); Assert.AreEqual("sha384ECDSA", cert.SignatureAlgorithm.FriendlyName); Assert.IsTrue(cert.HasPrivateKey); }
public void CreateWithP256Curve() { var options = new ECCertificateBuilderOptions { FullSubjectName = "CN=Test", ECCurve = ECNamedCurves.P256 }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); Assert.AreEqual("CN=Test", cert.Subject); Assert.AreEqual("sha256ECDSA", cert.SignatureAlgorithm.FriendlyName); Assert.IsTrue(cert.HasPrivateKey); }
public void P521CertificateCorrectlyParses() { var options = new ECCertificateBuilderOptions { FullSubjectName = "CN=Test", ECCurve = ECNamedCurves.P521 }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); var cng = ECDSACertificateParser.ParsePublicCertificate(cert); Assert.IsNotNull(cng); }
public void HeaderAndPayloadParsesCorrectly() { var options = new ECCertificateBuilderOptions { ECCurve = ECNamedCurves.P256, FullSubjectName = "CN=Test" }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); string headerJson; var token = JsonWebToken.EncodeUsingECDSA( new {id = 1, org = 1}, cert, new Dictionary<string, object> {{"alg", "ES256"}}, new JsonSerializerSettings(), out headerJson); var bits = token.Split('.'); Assert.AreEqual(3, bits.Length); Assert.AreEqual("eyJhbGciOiJFUzI1NiJ9", bits[0]); // HEADER Assert.AreEqual("eyJpZCI6MSwib3JnIjoxfQ", bits[1]); // DATA }
public void SurvivesExportImport() { var options = new ECCertificateBuilderOptions { FullSubjectName = "CN=Test", ECKeyName = "KeyTestTemp", HashingMethod = HashingMethods.Sha512 }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); var data = cert.Export(X509ContentType.Pkcs12, "password"); if (CngKey.Exists("KeyTestTemp")) { var objCngKey = CngKey.Open("KeyTestTemp"); objCngKey.Delete(); } var reloaded = new X509Certificate2(data, "password"); ECDSACertificateParser.ParsePrivateCertificate(reloaded); }
/// <summary> /// Create a ECDSA based certificate with the given options /// </summary> /// <param name="buildOptions">Allows for more advanced configuration</param> /// <returns>An exportable X509Certificate2 object (with private key)</returns> public static X509Certificate2 CreateNewSigningCertificate(ECCertificateBuilderOptions buildOptions) { if (buildOptions == null) { throw new ArgumentNullException("buildOptions"); } string keyName = buildOptions.ECKeyName ?? "ECDSAKey"; CngKey objCngKey = null; if (CngKey.Exists(keyName)) { objCngKey = CngKey.Open(keyName); objCngKey.Delete(); } var creationParameters = new CngKeyCreationParameters(); creationParameters.ExportPolicy = CngExportPolicies.AllowExport; creationParameters.KeyUsage = CngKeyUsages.Signing; CngAlgorithm keyAlg; switch (buildOptions.ECCurve ?? ECNamedCurves.P521) { case ECNamedCurves.P521: keyAlg = CngAlgorithm.ECDsaP521; break; case ECNamedCurves.P384: keyAlg = CngAlgorithm.ECDsaP384; break; case ECNamedCurves.P256: keyAlg = CngAlgorithm.ECDsaP256; break; default: throw new InvalidOperationException("Selected curve is not supported"); } objCngKey = CngKey.Create(keyAlg, keyName, creationParameters); var name = new X500DistinguishedName(buildOptions.FullSubjectName); X509CertificateSignatureAlgorithm certAlg; switch (buildOptions.HashingMethod ?? HashingMethods.Sha256) { case HashingMethods.Sha1: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha1; break; case HashingMethods.Sha256: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha256; break; case HashingMethods.Sha384: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha384; break; case HashingMethods.Sha512: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha512; break; default: throw new InvalidOperationException("Selected hashing method is not supported"); } var options = new X509CertificateCreationParameters(name) { SignatureAlgorithm = certAlg, TakeOwnershipOfKey = true }; return(objCngKey.CreateSelfSignedCertificate(options)); }
public void ECDSAKeySizeDoesNotMatchThrowsError() { var options = new ECCertificateBuilderOptions { FullSubjectName = "CN=Test", ECCurve = ECNamedCurves.P521, HashingMethod = HashingMethods.Sha256, ECKeyName = "ECDSA_Test" }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); string headerJson; var token = JsonWebToken.EncodeUsingECDSA(new {id = 1, org = 2}, cert, out headerJson); cert = ECCertificateBuilder.CreateNewSigningCertificate(new ECCertificateBuilderOptions { ECCurve = ECNamedCurves.P256, FullSubjectName = "CN=Test" }); try { string payloadJson; JsonWebToken.DecodeUsingECDSA<object>(token, cert, out headerJson, out payloadJson); } catch (SignatureVerificationException ex) { Assert.AreEqual("Key size does not match: ES256 vs ES521", ex.Message); return; } Assert.Fail(); }
public void UnknownJWTAlgorithmThrowsError() { var options = new ECCertificateBuilderOptions { ECCurve = ECNamedCurves.P256, FullSubjectName = "CN=Test" }; var cert = ECCertificateBuilder.CreateNewSigningCertificate(options); string headerJson; var token = JsonWebToken.EncodeUsingECDSA(new {id = 1, org = 2}, cert, out headerJson); var split = token.Split('.'); split[0] = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0EifQ"; // switch header token = string.Join(".", split); try { string payloadJson; JsonWebToken.DecodeUsingECDSA<object>(token, cert, out headerJson, out payloadJson); } catch (SignatureVerificationException ex) { Assert.AreEqual("Unsupported signing algorithm: RSA", ex.Message); return; } Assert.Fail(); }
/// <summary> /// Create a ECDSA based certificate with the given options /// </summary> /// <param name="buildOptions">Allows for more advanced configuration</param> /// <returns>An exportable X509Certificate2 object (with private key)</returns> public static X509Certificate2 CreateNewSigningCertificate(ECCertificateBuilderOptions buildOptions) { if(buildOptions == null) { throw new ArgumentNullException("buildOptions"); } string keyName = buildOptions.ECKeyName ?? "ECDSAKey"; CngKey objCngKey = null; if (CngKey.Exists(keyName)) { objCngKey = CngKey.Open(keyName); objCngKey.Delete(); } var creationParameters = new CngKeyCreationParameters(); creationParameters.ExportPolicy = CngExportPolicies.AllowExport; creationParameters.KeyUsage = CngKeyUsages.Signing; CngAlgorithm keyAlg; switch(buildOptions.ECCurve ?? ECNamedCurves.P521) { case ECNamedCurves.P521: keyAlg = CngAlgorithm.ECDsaP521; break; case ECNamedCurves.P384: keyAlg = CngAlgorithm.ECDsaP384; break; case ECNamedCurves.P256: keyAlg = CngAlgorithm.ECDsaP256; break; default: throw new InvalidOperationException("Selected curve is not supported"); } objCngKey = CngKey.Create(keyAlg, keyName, creationParameters); var name = new X500DistinguishedName(buildOptions.FullSubjectName); X509CertificateSignatureAlgorithm certAlg; switch(buildOptions.HashingMethod ?? HashingMethods.Sha256) { case HashingMethods.Sha1: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha1; break; case HashingMethods.Sha256: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha256; break; case HashingMethods.Sha384: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha384; break; case HashingMethods.Sha512: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha512; break; default: throw new InvalidOperationException("Selected hashing method is not supported"); } var options = new X509CertificateCreationParameters(name) { SignatureAlgorithm = certAlg, TakeOwnershipOfKey = true }; return objCngKey.CreateSelfSignedCertificate(options); }