Пример #1
0
        private static ECDsa LoadPrivateKey(string pem)
        {
            var reader     = new PemReader(new StringReader(pem));
            var keyPair    = (AsymmetricCipherKeyPair)reader.ReadObject();
            var p          = (ECPrivateKeyParameters)keyPair.Private;
            var privKeyInt = p.D;
            var parameters = SecNamedCurves.GetByName("secp256r1");
            var ecPoint    = parameters.G.Multiply(privKeyInt);
            var privKeyX   = ecPoint.Normalize().XCoord.ToBigInteger().ToByteArrayUnsigned();
            var privKeyY   = ecPoint.Normalize().YCoord.ToBigInteger().ToByteArrayUnsigned();

#if NETSTANDARD2_0
            return(ECDsa.Create(new ECParameters
            {
                Curve = ECCurve.NamedCurves.nistP256,
                D = privKeyInt.ToByteArrayUnsigned(),
                Q = new ECPoint
                {
                    X = privKeyX,
                    Y = privKeyY
                }
            }));
#else
            var x     = EccKey.New(privKeyX, privKeyY, privKeyInt.ToByteArrayUnsigned());
            var ecdsa = new ECDsaCng(x);
            return(ecdsa);
#endif
        }
Пример #2
0
        public void Derive128BitKey()
        {
            // https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-23#appendix-C

            //given
            byte[] bob_x = Base64Url.Decode("weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ");
            byte[] bob_y = Base64Url.Decode("e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck");
            byte[] bob_d = Base64Url.Decode("VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw");

            byte[] ephemeral_x = Base64Url.Decode("gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0");
            byte[] ephemeral_y = Base64Url.Decode("SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps");

            byte[] algorithmId = new byte[] { 0, 0, 0, 7, 65, 49, 50, 56, 71, 67, 77 };
            byte[] partyUInfo  = new byte[] { 0, 0, 0, 5, 65, 108, 105, 99, 101 };
            byte[] partyVInfo  = new byte[] { 0, 0, 0, 3, 66, 111, 98 };
            byte[] suppPubInfo = new byte[] { 0, 0, 0, 128 };

            //when
            byte[] key = ConcatKDF.DeriveKey(EccKey.New(ephemeral_x, ephemeral_y, usage: CngKeyUsages.KeyAgreement), EccKey.New(bob_x, bob_y, bob_d, usage: CngKeyUsages.KeyAgreement), 128, algorithmId, partyVInfo, partyUInfo, suppPubInfo);

            string test = Base64Url.Encode(key);

            //then
            Assert.Equal(test, "VqqN6vgjbSBcIijNcacQGg");
        }
Пример #3
0
        public virtual byte[] Unwrap(byte[] encryptedCek, object key, int cekSizeBits, IDictionary <string, object> header)
        {
            CngKey privateKey = null;

            if (key is Jwk jwk)
            {
                if (jwk.Kty == Jwk.KeyTypes.EC)
                {
                    privateKey = jwk.CngKey(CngKeyUsages.KeyAgreement);
                }
            }

            privateKey = privateKey ?? Ensure.Type <CngKey>(key, "EcdhKeyManagement alg expects key to be of CngKey or Jwk types with kty='EC'.");

            Ensure.Contains(header, new[] { "epk" }, "EcdhKeyManagement algorithm expects 'epk' key param in JWT header, but was not found");
            Ensure.Contains(header, new[] { algIdHeader }, "EcdhKeyManagement algorithm expects 'enc' header to be present in JWT header, but was not found");

            var epk = (IDictionary <string, object>)header["epk"];

            Ensure.Contains(epk, new[] { "x", "y", "crv" }, "EcdhKeyManagement algorithm expects 'epk' key to contain 'x','y' and 'crv' fields.");

            var x = Base64Url.Decode((string)epk["x"]);
            var y = Base64Url.Decode((string)epk["y"]);

            var externalPublicKey = EccKey.New(x, y, usage: CngKeyUsages.KeyAgreement);

            return(DeriveKey(header, cekSizeBits, externalPublicKey, privateKey));
        }
Пример #4
0
        private byte[] NewKey(int keyLength, object key, IDictionary <string, object> header)
        {
            CngKey recieverPubKey = null;

            if (key is Jwk jwk)
            {
                if (jwk.Kty == Jwk.KeyTypes.EC)
                {
                    recieverPubKey = jwk.CngKey(CngKeyUsages.KeyAgreement);
                }
            }

            recieverPubKey = recieverPubKey ?? Ensure.Type <CngKey>(key, "EcdhKeyManagement alg expects key to be of CngKey or Jwk types with kty='EC'.");

            EccKey ephemeral = EccKey.Generate(recieverPubKey);

            IDictionary <string, object> epk = new Dictionary <string, object>();

            epk["kty"] = "EC";
            epk["x"]   = Base64Url.Encode(ephemeral.X);
            epk["y"]   = Base64Url.Encode(ephemeral.Y);
            epk["crv"] = ephemeral.Curve();

            header["epk"] = epk;

            return(DeriveKey(header, keyLength, recieverPubKey, ephemeral.Key));
        }
Пример #5
0
        private static CngKey Ecc256Public(CngKeyUsages usage = CngKeyUsages.Signing)
        {
            byte[] x = { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
            byte[] y = { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
            byte[] d = { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 };

            return(EccKey.New(x, y, usage: usage));
        }
Пример #6
0
        /// <summary>
        /// 解析token内的内容
        /// </summary>
        /// <param name="accessToken">签权</param>
        /// <returns>Json对象</returns>
        public static JObject GetData(string accessToken)
        {
            var    publicKey = EccKey.New(x, y, d);
            string json      = Jose.JWT.Decode(accessToken, publicKey, JwsAlgorithm.ES256);

            return(JObject.Parse(json));
            //string OpenId = Obj["openId"].ToString();
            //return OpenId;
        }
 /// <summary>JwkToCng</summary>
 /// <param name="jwk">JObject</param>
 /// <returns>CngKey(公開鍵)</returns>
 public static CngKey JwkToCng(Dictionary <string, string> jwk)
 {
     // 楕円曲線
     // 不要
     // 公開鍵の部分
     return(EccKey.New(
                CustomEncode.FromBase64UrlString((string)jwk[JwtConst.x]),
                CustomEncode.FromBase64UrlString((string)jwk[JwtConst.y])));
 }
Пример #8
0
        /// <summary>
        /// 生成token
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string CreateAccessToken(string name)
        {
            var payload = new Dictionary <string, object>()
            {
                { "name", name },
                { "exp", DateTime.Now.AddDays(3) }
            };
            var privateKey = EccKey.New(x, y, d);

            return(Jose.JWT.Encode(payload, privateKey, JwsAlgorithm.ES256));
        }
Пример #9
0
        private byte[] NewKey(int keyLength, object key, IDictionary <string, object> header)
        {
            CngKey cngKey = Ensure.Type <CngKey>(key, "EcdhKeyManagement alg expects key to be of CngKey type.", new object[0]);
            EccKey eccKey = EccKey.Generate(cngKey);
            IDictionary <string, object> strs = new Dictionary <string, object>();

            strs["kty"]   = "EC";
            strs["x"]     = Base64Url.Encode(eccKey.X);
            strs["y"]     = Base64Url.Encode(eccKey.Y);
            strs["crv"]   = this.Curve(cngKey);
            header["epk"] = strs;
            return(this.DeriveKey(header, keyLength, cngKey, eccKey.Key));
        }
Пример #10
0
        public virtual byte[] Unwrap(byte[] encryptedCek, object key, int cekSizeBits, IDictionary <string, object> header)
        {
            CngKey cngKey = Ensure.Type <CngKey>(key, "EcdhKeyManagement alg expects key to be of CngKey type.", new object[0]);

            Ensure.Contains(header, new string[] { "epk" }, "EcdhKeyManagement algorithm expects 'epk' key param in JWT header, but was not found", new object[0]);
            Ensure.Contains(header, new string[] { this.algIdHeader }, "EcdhKeyManagement algorithm expects 'enc' header to be present in JWT header, but was not found", new object[0]);
            IDictionary <string, object> item = (IDictionary <string, object>)header["epk"];

            Ensure.Contains(item, new string[] { "x", "y", "crv" }, "EcdhKeyManagement algorithm expects 'epk' key to contain 'x','y' and 'crv' fields.", new object[0]);
            byte[] numArray  = Base64Url.Decode((string)item["x"]);
            byte[] numArray1 = Base64Url.Decode((string)item["y"]);
            CngKey cngKey1   = EccKey.New(numArray, numArray1, null, CngKeyUsages.KeyAgreement);

            return(this.DeriveKey(header, cekSizeBits, cngKey1, cngKey));
        }
Пример #11
0
        internal static void VerifyTokenSignature(string JwsJson, JObject jwk)
        {
            if ("EC".Equals(jwk["kty"].ToString()))
            {
                byte[] x = Base64Url.Decode(jwk["x"].ToString());
                byte[] y = Base64Url.Decode(jwk["y"].ToString());

#if (NETCOREAPP2_1 || NETSTANDARD2_0)
                var publicKey = ECDsa.Create(new ECParameters
                {
                    Curve = ECCurve.NamedCurves.nistP256,
                    Q     = new ECPoint
                    {
                        X = x,
                        Y = y
                    },
                    D = null
                });

                var decoded = JWT.Decode(JwsJson, publicKey);
#else
                CngKey cngKey  = EccKey.New(x, y);
                var    decoded = JWT.Decode(JwsJson, cngKey);
#endif
                return;
            }
            else if ("RSA".Equals(jwk["kty"].ToString()))
            {
                byte[] n = Base64Url.Decode(jwk["n"].ToString());
                byte[] e = Base64Url.Decode(jwk["e"].ToString());

                using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
                {
                    RSAParameters rsaParameters = new RSAParameters
                    {
                        Exponent = e,
                        Modulus  = n
                    };
                    RSA.ImportParameters(rsaParameters);
                    JWT.Decode(JwsJson, RSA);
                    return;
                }

                /*var publicKey = RsaKey.New(e, n);
                 * var decoded = JWT.Decode(JwsJson, publicKey);
                 * return;*/
            }
        }
Пример #12
0
        private byte[] NewKey(int keyLength, object key, IDictionary <string, object> header)
        {
            var recieverPubKey = Ensure.Type <CngKey>(key, "EcdhKeyManagement alg expects key to be of CngKey type.");

            EccKey ephemeral = EccKey.Generate(recieverPubKey);

            IDictionary <string, object> epk = new Dictionary <string, object>();

            epk["kty"] = "EC";
            epk["x"]   = Base64Url.Encode(ephemeral.X);
            epk["y"]   = Base64Url.Encode(ephemeral.Y);
            epk["crv"] = Curve(recieverPubKey);

            header["epk"] = epk;

            return(DeriveKey(header, keyLength, recieverPubKey, ephemeral.Key));
        }
        /// <summary>
        /// Elliptic Curve Diffie Hellman key agreement with AES Key Wrap using 256 bit key
        /// AES GCM Key Wrap Algorithm using 256 bit keys
        /// </summary>
        /// <param name="password"></param>
        /// <param name="plainText"></param>
        /// <returns></returns>
        public static string Encrypt(ECParameters exportParameters, string plainText)
        {
            // Claims see https://tools.ietf.org/html/rfc7519#section-4.1
            var nonEncryptedHeaders = new Dictionary <string, object>
            {
                { "sub", "*****@*****.**" },
                { "exp", 1300819380 }
            };

            var publicKey = EccKey.New(exportParameters.Q.X, exportParameters.Q.Y, exportParameters.D, CngKeyUsages.KeyAgreement);

            // Not Implemented for NETSTANDARD 1.4
            // https://github.com/dvsekhvalnov/jose-jwt/blob/e54de3bb706edf294053b4b86f0db47333d433ef/jose-jwt/crypto/ConcatKDF.cs#L43
            var token = JWT.Encode(plainText, publicKey, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM, extraHeaders: nonEncryptedHeaders);

            return(token);
        }
Пример #14
0
        public virtual byte[] Unwrap(byte[] encryptedCek, object key, int cekSizeBits, IDictionary <string, object> header)
        {
            var privateKey = Ensure.Type <CngKey>(key, "EcdhKeyManagement alg expects key to be of CngKey type.");

            Ensure.Contains(header, new[] { "epk" }, "EcdhKeyManagement algorithm expects 'epk' key param in JWT header, but was not found");
            Ensure.Contains(header, new[] { algIdHeader }, "EcdhKeyManagement algorithm expects 'enc' header to be present in JWT header, but was not found");

            var jObject = (JObject)header["epk"];
            var epk     = jObject.ToObject <Dictionary <string, object> >();

            Ensure.Contains(epk, new[] { "x", "y", "crv" }, "EcdhKeyManagement algorithm expects 'epk' key to contain 'x','y' and 'crv' fields.");

            var x = Base64Url.Decode((string)epk["x"]);
            var y = Base64Url.Decode((string)epk["y"]);

            var externalPublicKey = EccKey.New(x, y, usage: CngKeyUsages.KeyAgreement);

            return(DeriveKey(header, cekSizeBits, externalPublicKey, privateKey));
        }
Пример #15
0
        public void InvalidCurveAttack()
        {
            Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "This requires CNG, which is Windows Only.");

            // https://www.cs.bris.ac.uk/Research/CryptographySecurity/RWC/2017/nguyen.quan.pdf
            // Attack exploits some ECDH implementations which do not check
            // that ephemeral public key is on the private key's curve.

            byte[] x = Base64Url.Decode("weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ");
            byte[] y = Base64Url.Decode("e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck");
            byte[] d = Base64Url.Decode("VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw");

            var privateKey = EccKey.New(x, y, d, usage: CngKeyUsages.KeyAgreement);

            //JWT encrypted with attacker private key, which is equals to (reciever_pk mod 113)
            var attackMod113 =
                "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiZ1RsaTY1ZVRRN3otQmgxNDdmZjhLM203azJVaURpRzJMcFlrV0FhRkpDYyIsInkiOiJjTEFuakthNGJ6akQ3REpWUHdhOUVQclJ6TUc3ck9OZ3NpVUQta2YzMEZzIiwiY3J2IjoiUC0yNTYifX0.qGAdxtEnrV_3zbIxU2ZKrMWcejNltjA_dtefBFnRh9A2z9cNIqYRWg.pEA5kX304PMCOmFSKX_cEg.a9fwUrx2JXi1OnWEMOmZhXd94-bEGCH9xxRwqcGuG2AMo-AwHoljdsH5C_kcTqlXS5p51OB1tvgQcMwB5rpTxg.72CHiYFecyDvuUa43KKT6w";

            //JWT encrypted with attacker private key, which is equals to (reciever_pk mod 2447)
            var attackMod2447 =
                "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiWE9YR1E5XzZRQ3ZCZzN1OHZDSS1VZEJ2SUNBRWNOTkJyZnFkN3RHN29RNCIsInkiOiJoUW9XTm90bk56S2x3aUNuZUprTElxRG5UTnc3SXNkQkM1M1ZVcVZqVkpjIiwiY3J2IjoiUC0yNTYifX0.UGb3hX3ePAvtFB9TCdWsNkFTv9QWxSr3MpYNiSBdW630uRXRBT3sxw.6VpU84oMob16DxOR98YTRw.y1UslvtkoWdl9HpugfP0rSAkTw1xhm_LbK1iRXzGdpYqNwIG5VU33UBpKAtKFBoA1Kk_sYtfnHYAvn-aes4FTg.UZPN8h7FcvA5MIOq-Pkj8A";

            try
            {
                JWT.Decode(attackMod113, privateKey);
                Assert.True(false, "Should fail with CrytographicException");
            }
            catch (CryptographicException e)
            {
                Console.WriteLine(e);
            }

            try
            {
                JWT.Decode(attackMod2447, privateKey);
                Assert.True(false, "Should fail with CrytographicException");
            }
            catch (CryptographicException e)
            {
                Console.WriteLine(e);
            }
        }
Пример #16
0
        /// <summary>JoseJwt</summary>
        private static void JoseJwt()
        {
            #region Variables

            #region Env
            OperatingSystem os = Environment.OSVersion;

            // https://github.com/dotnet/corefx/issues/29404#issuecomment-385287947
            //   *.pfxから証明書を開く場合、X509KeyStorageFlags.Exportableの指定が必要な場合がある。
            //   Linuxのキーは常にエクスポート可能だが、WindowsやMacOSでは必ずしもそうではない。
            X509KeyStorageFlags x509KSF = 0;
            if (os.Platform == PlatformID.Win32NT)
            {
                x509KSF = X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable;
            }
            else //if (os.Platform == PlatformID.Unix)
            {
                x509KSF = X509KeyStorageFlags.DefaultKeySet;
            }
            #endregion

            #region Token
            string token = "";
            IDictionary <string, object> headers = null;
            IDictionary <string, object> payload = null;
            payload = new Dictionary <string, object>()
            {
                { "sub", "*****@*****.**" },
                { "exp", 1300819380 }
            };
            #endregion

            #region Keys

            byte[] secretKey = null;
            byte[] x         = null;
            byte[] y         = null;
            byte[] d         = null;

            X509Certificate2 publicX509Key  = null;
            X509Certificate2 privateX509Key = null;

            RSA rsa = null;
            //DSA dsa = null;

            CngKey publicKeyOfCng  = null;
            CngKey privateKeyOfCng = null;

            #endregion

            #endregion

            #region JWT

            #region Unsecured JWT
            // Creating Plaintext (unprotected) Tokens
            // https://github.com/dvsekhvalnov/jose-jwt#creating-plaintext-unprotected-tokens
            token = "";
            token = JWT.Encode(payload, null, JwsAlgorithm.none);
            MyDebug.OutputDebugAndConsole("JwsAlgorithm.none", token);
            #endregion

            #region JWS (Creating signed Tokens)
            // https://github.com/dvsekhvalnov/jose-jwt#creating-signed-tokens

            #region HS-* family
            // HS256, HS384, HS512
            // https://github.com/dvsekhvalnov/jose-jwt#hs--family
            secretKey = new byte[] { 164, 60, 194, 0, 161, 189, 41, 38, 130, 89, 141, 164, 45, 170, 159, 209, 69, 137, 243, 216, 191, 131, 47, 250, 32, 107, 231, 117, 37, 158, 225, 234 };
            token     = "";
            token     = JWT.Encode(payload, secretKey, JwsAlgorithm.HS256);
            Program.VerifyResult("JwsAlgorithm.HS256", token, secretKey);
            #endregion

            #region RS-* and PS-* family
            // RS256, RS384, RS512 and PS256, PS384, PS512
            // https://github.com/dvsekhvalnov/jose-jwt#rs--and-ps--family
            // X509Certificate2 x509Certificate2 = new X509Certificate2();
            privateX509Key = new X509Certificate2(Program.PrivateRsaX509Path, Program.PfxPassword, x509KSF);
            publicX509Key  = new X509Certificate2(Program.PublicRsaX509Path, "", x509KSF);

            token = "";


#if NETCORE
            rsa = (RSA)privateX509Key.PrivateKey;
#else
            // .net frameworkでは、何故かコレが必要。
            rsa = (RSA)AsymmetricAlgorithmCmnFunc.CreateSameKeySizeSP(privateX509Key.PrivateKey);
#endif
            token = JWT.Encode(payload, rsa, JwsAlgorithm.RS256);
            Program.VerifyResult("JwsAlgorithm.RS256", token, rsa);

            #endregion

            #region ES- * family
            // ES256, ES384, ES512 ECDSA signatures
            // https://github.com/dvsekhvalnov/jose-jwt#es---family

            x = new byte[] { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
            y = new byte[] { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
            d = new byte[] { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 };

            if (os.Platform == PlatformID.Win32NT)
            {
                // https://github.com/dvsekhvalnov/jose-jwt/blob/master/jose-jwt/Security/Cryptography/EccKey.cs
                privateKeyOfCng = EccKey.New(x, y, d);
                publicKeyOfCng  = EccKey.New(x, y);

                token = "";
                token = JWT.Encode(payload, privateKeyOfCng, JwsAlgorithm.ES256);
                Program.VerifyResult("JwsAlgorithm.ES256", token, publicKeyOfCng);
            }
            else //if (os.Platform == PlatformID.Unix)
            {
#if NETCORE
                ECParameters eCParameters = new ECParameters();

                // Curve
                eCParameters.Curve =
                    EccPublicKeyConverter.GetECCurveFromCrvString(
                        EccPublicKeyConverter.GetCrvStringFromXCoordinate(x));

                // x, y, d
                eCParameters.Q.X = x;
                eCParameters.Q.Y = y;
                eCParameters.D   = d;
                ECDsaOpenSsl eCDsaOpenSsl = new ECDsaOpenSsl(eCParameters.Curve);
                eCDsaOpenSsl.ImportParameters(eCParameters);

                token = "";
                token = JWT.Encode(payload, eCDsaOpenSsl, JwsAlgorithm.ES256);
                Program.VerifyResult("JwsAlgorithm.ES256", token, eCDsaOpenSsl);
#endif
            }

#if NETCORE || NET47
            privateX509Key = new X509Certificate2(Program.PrivateECDsaX509Path, Program.PfxPassword);
            publicX509Key  = new X509Certificate2(Program.PublicECDsaX509Path, "");

            try
            {
#if NETCORE
                if (os.Platform == PlatformID.Win32NT)
                {
                }
                else //if (os.Platform == PlatformID.Unix)
                {
                    // ECCurveを分析してみる。
                    ECCurve eCCurve = ((ECDsaOpenSsl)privateX509Key.GetECDsaPrivateKey()).ExportExplicitParameters(true).Curve;
                    MyDebug.OutputDebugAndConsole("Inspect ECCurve", ObjectInspector.Inspect(eCCurve));
                }
#endif
                token = "";
                token = JWT.Encode(payload, privateX509Key.GetECDsaPrivateKey(), JwsAlgorithm.ES256);
                Program.VerifyResult("JwsAlgorithm.ES256", token, publicX509Key.GetECDsaPublicKey());
            }
            catch (Exception ex)
            {
                MyDebug.OutputDebugAndConsole("JwsAlgorithm.ES256", ex.GetType().ToString() + ", " + ex.Message);
            }
#endif

            #endregion

            #endregion

            #region JWE (Creating encrypted Tokens)
            // https://github.com/dvsekhvalnov/jose-jwt#creating-encrypted-tokens

            #region RSA-* key management family of algorithms
            // RSA-OAEP-256, RSA-OAEP and RSA1_5 key
            // https://github.com/dvsekhvalnov/jose-jwt#rsa--key-management-family-of-algorithms
            privateX509Key = new X509Certificate2(Program.PrivateRsaX509Path, Program.PfxPassword, x509KSF);
            publicX509Key  = new X509Certificate2(Program.PublicRsaX509Path, "", x509KSF);

            // RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256
            token = "";
            token = JWT.Encode(payload, publicX509Key.PublicKey.Key, JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256);
            Program.VerifyResult("JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256", token, privateX509Key.PrivateKey);

            // RSAES-OAEP and AES GCM
            try
            {
                token = "";
                token = JWT.Encode(payload, publicX509Key.PublicKey.Key, JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM);
                Program.VerifyResult("JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM", token, privateX509Key.PrivateKey);
            }
            catch (Exception ex)
            {
                // Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll' at ubunntu
                MyDebug.OutputDebugAndConsole("JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM", ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region Other key management family of algorithms

            secretKey = new byte[] { 164, 60, 194, 0, 161, 189, 41, 38, 130, 89, 141, 164, 45, 170, 159, 209, 69, 137, 243, 216, 191, 131, 47, 250, 32, 107, 231, 117, 37, 158, 225, 234 };

            #region DIR direct pre-shared symmetric key family of algorithms
            // https://github.com/dvsekhvalnov/jose-jwt#dir-direct-pre-shared-symmetric-key-family-of-algorithms
            token = "";
            token = JWT.Encode(payload, secretKey, JweAlgorithm.DIR, JweEncryption.A128CBC_HS256);
            Program.VerifyResult("JweAlgorithm.DIR, JweEncryption.A128CBC_HS256", token, secretKey);
            #endregion

            #region AES Key Wrap key management family of algorithms
            // AES128KW, AES192KW and AES256KW key management
            // https://github.com/dvsekhvalnov/jose-jwt#aes-key-wrap-key-management-family-of-algorithms
            token = "";
            token = JWT.Encode(payload, secretKey, JweAlgorithm.A256KW, JweEncryption.A256CBC_HS512);
            Program.VerifyResult("JweAlgorithm.A256KW, JweEncryption.A256CBC_HS512", token, secretKey);
            #endregion

            #region AES GCM Key Wrap key management family of algorithms
            // AES128GCMKW, AES192GCMKW and AES256GCMKW key management
            // https://github.com/dvsekhvalnov/jose-jwt#aes-gcm-key-wrap-key-management-family-of-algorithms
            try
            {
                token = "";
                token = JWT.Encode(payload, secretKey, JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512);
                Program.VerifyResult("JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512", token, secretKey);
            }
            catch (Exception ex)
            {
                // Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll' at ubunntu
                MyDebug.OutputDebugAndConsole("JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512", ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region ECDH-ES and ECDH-ES with AES Key Wrap key management family of algorithms
            // ECDH-ES and ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW key management
            // https://github.com/dvsekhvalnov/jose-jwt#ecdh-es-and-ecdh-es-with-aes-key-wrap-key-management-family-of-algorithms
            try
            {
                x = new byte[] { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
                y = new byte[] { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
                publicKeyOfCng = EccKey.New(x, y, usage: CngKeyUsages.KeyAgreement);
                token          = "";
                token          = JWT.Encode(payload, publicKeyOfCng, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM);
                Program.VerifyResult("JweAlgorithm.ECDH_ES, JweEncryption.A256GCM", token, publicKeyOfCng);
            }
            catch (Exception ex)
            {
                // System.NotImplementedException: 'not yet'
                MyDebug.OutputDebugAndConsole("JweAlgorithm.ECDH_ES, JweEncryption.A256GCM", ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region PBES2 using HMAC SHA with AES Key Wrap key management family of algorithms
            token = "";
            token = JWT.Encode(payload, "top secret", JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512);
            Program.VerifyResult("JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512", token, "top secret");
            #endregion

            #endregion

            #endregion

            #endregion

            #region ELSE

            #region Additional utilities
            // https://github.com/dvsekhvalnov/jose-jwt#additional-utilities

            #region Adding extra headers
            // https://github.com/dvsekhvalnov/jose-jwt#adding-extra-headers

            headers = new Dictionary <string, object>()
            {
                { "typ", "JWT" },
                { "cty", "JWT" },
                { "keyid", "111-222-333" }
            };

            privateX509Key = new X509Certificate2(Program.PrivateRsaX509Path, Program.PfxPassword, x509KSF);
            publicX509Key  = new X509Certificate2(Program.PublicRsaX509Path, "", x509KSF);

#if NETCORE
            rsa = (RSA)privateX509Key.PrivateKey;
#else
            // .net frameworkでは、何故かコレが必要。
            rsa = (RSA)AsymmetricAlgorithmCmnFunc.CreateSameKeySizeSP(privateX509Key.PrivateKey);
#endif

            token = "";
            token = JWT.Encode(payload, rsa, JwsAlgorithm.RS256, extraHeaders: headers);
            Program.VerifyResult("Adding extra headers to RS256", token, rsa);
            #endregion

            #region Strict validation
            // https://github.com/dvsekhvalnov/jose-jwt#strict-validation
            // 厳密な検証では、Algorithmを指定可能
            MyDebug.OutputDebugAndConsole("Strict validation(RS256)", JWT.Decode(token, rsa, JwsAlgorithm.RS256));
            #endregion

            #region Two-phase validation
            // https://github.com/dvsekhvalnov/jose-jwt#two-phase-validation
            // ヘッダのkeyidクレームからキーを取り出して復号化する方法。
            //headers = JWT.Headers(token);
            // ・・・
            //string hoge = JWT.Decode(token, "key");
            #endregion

            #region Working with binary payload
            // https://github.com/dvsekhvalnov/jose-jwt#working-with-binary-payload
            #endregion

            #endregion

            #region Settings
            // https://github.com/dvsekhvalnov/jose-jwt#settings
            // グローバル設定

            #region Example of JWTSettings
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-jwtsettings

            #endregion

            #region Customizing json <-> object parsing & mapping
            // https://github.com/dvsekhvalnov/jose-jwt#customizing-json---object-parsing--mapping
            // マッピング
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-newtonsoftjson-mapper
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-servicestack-mapper

            #endregion

            #region Customizing algorithm implementations
            // https://github.com/dvsekhvalnov/jose-jwt#customizing-algorithm-implementations
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-custom-algorithm-implementation
            #endregion

            #region Providing aliases
            // https://github.com/dvsekhvalnov/jose-jwt#providing-aliases
            #endregion

            #endregion

            #region Dealing with keys
            // https://github.com/dvsekhvalnov/jose-jwt#dealing-with-keys
            // https://github.com/dvsekhvalnov/jose-jwt#rsacryptoserviceprovider
            // - http://stackoverflow.com/questions/7444586/how-can-i-sign-a-file-using-rsa-and-sha256-with-net
            // - http://hintdesk.com/c-how-to-fix-invalid-algorithm-specified-when-signing-with-sha256/
            // https://github.com/dvsekhvalnov/jose-jwt#if-you-have-only-rsa-private-key
            // - http://www.donaldsbaconbytes.com/2016/08/create-jwt-with-a-private-rsa-key/
            #endregion

            #region Strong-Named assembly
            // https://github.com/dvsekhvalnov/jose-jwt#strong-named-assembly
            // - https://github.com/dvsekhvalnov/jose-jwt/issues/5
            // - https://github.com/brutaldev/StrongNameSigner
            #endregion

            #region More examples
            // https://github.com/dvsekhvalnov/jose-jwt#more-examples
            // https://github.com/dvsekhvalnov/jose-jwt/blob/master/UnitTests/TestSuite.cs
            #endregion

            #endregion
        }
Пример #17
0
        public static void hogehoge(string[] args)
        {
            try
            {
                #region Variables

                #region Env

                // https://github.com/dotnet/corefx/issues/29404#issuecomment-385287947
                //   *.pfxから証明書を開く場合、X509KeyStorageFlags.Exportableの指定が必要な場合がある。
                //   Linuxのキーは常にエクスポート可能だが、WindowsやMacOSでは必ずしもそうではない。
                X509KeyStorageFlags x509KSF = 0;
                x509KSF = X509KeyStorageFlags.DefaultKeySet;
                #endregion

                #region Token
                string token = "";
                IDictionary <string, object> headers = null;
                IDictionary <string, object> payload = null;
                payload = new Dictionary <string, object>()
                {
                    { "sub", "*****@*****.**" },
                    { "exp", 1300819380 }
                };
                #endregion

                #region Keys
                string jwk = "";

                byte[] secretKey = null;
                byte[] x         = null;
                byte[] y         = null;
                byte[] d         = null;

                string           privateX509Path = "";
                string           publicX509Path  = "";
                X509Certificate2 publicX509Key   = null;
                X509Certificate2 privateX509Key  = null;

                RSA rsa = null;
                //DSA dsa = null;

                CngKey publicKeyOfCng = null;
                //CngKey privateKeyOfCng = null;
                ECParameters eCParameters = new ECParameters();
                #endregion

                #region DigitalSign
                byte[] data = CustomEncode.StringToByte("hogehoge", CustomEncode.UTF_8);
                byte[] sign = null;
                #endregion

                #endregion

                #region Test of the X.509 Certificates

                #region RSA
                privateX509Path = @"SHA256RSA.pfx";
                publicX509Path  = @"SHA256RSA.cer";
                privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KSF);
                publicX509Key   = new X509Certificate2(publicX509Path, "", x509KSF);
                WriteLine.InspectPrivateX509Key("RSA", privateX509Key);
                WriteLine.InspectPublicX509Key("RSA", publicX509Key);
                #endregion

                #region DSA
                // https://github.com/dotnet/corefx/issues/18733#issuecomment-296723615
                privateX509Path = @"SHA256DSA.pfx";
                publicX509Path  = @"SHA256DSA.cer";
                privateX509Key  = new X509Certificate2(privateX509Path, "test");
                publicX509Key   = new X509Certificate2(publicX509Path, "");
                WriteLine.InspectPrivateX509Key("DSA", privateX509Key);
                WriteLine.InspectPublicX509Key("DSA", publicX509Key);
                DSA privateDSA = privateX509Key.GetDSAPrivateKey();
                WriteLine.OutPutDebugAndConsole("privateDSA",
                                                (privateDSA == null ? "is null" : "is not null"));
                //DSA publicDSA = null; // publicX509Key.GetDSAPublicKey(); // Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException
                #endregion

                #region ECDsa
                // https://github.com/dotnet/corefx/issues/18733#issuecomment-296723615
                privateX509Path = @"SHA256ECDSA.pfx";
                publicX509Path  = @"SHA256ECDSA.cer";
                privateX509Key  = new X509Certificate2(privateX509Path, "test");
                publicX509Key   = new X509Certificate2(publicX509Path, "");
                WriteLine.InspectPrivateX509Key("ECDsa", privateX509Key);
                WriteLine.InspectPublicX509Key("ECDsa", publicX509Key);

                ECDsa privateECDsa = privateX509Key.GetECDsaPrivateKey();
                WriteLine.OutPutDebugAndConsole("privateECDsa",
                                                (privateECDsa == null ? "is null" : "is not null"));

                ECDsa publicECDsa = publicX509Key.GetECDsaPublicKey();
                WriteLine.OutPutDebugAndConsole("publicECDsa",
                                                (publicECDsa == null ? "is null" : "is not null"));
                #endregion

                #endregion

                WriteLine.OutPutDebugAndConsole("----------------------------------------------------------------------------------------------------");

                #region Test of the OpenTouryo.Public.Security.

                DigitalSignParam dsParam = null;
                DigitalSignXML   dsXML   = null;
                DigitalSignX509  dsX509  = null;

                #region RSA
                dsParam = new DigitalSignParam(EnumDigitalSignAlgorithm.RsaOpenSsl_SHA256);
                sign    = dsParam.Sign(data);
                WriteLine.OutPutDebugAndConsole("DigitalSignParam.Verify(RS256)",
                                                dsParam.Verify(data, sign).ToString());

                dsXML = new DigitalSignXML(EnumDigitalSignAlgorithm.RsaOpenSsl_SHA256);
                sign  = dsXML.Sign(data);
                WriteLine.OutPutDebugAndConsole("DigitalSignXML.Verify(RS256)",
                                                dsXML.Verify(data, sign).ToString());

                dsX509 = new DigitalSignX509(@"SHA256RSA.pfx", "test", "SHA256");
                sign   = dsX509.Sign(data);
                WriteLine.OutPutDebugAndConsole("DigitalSignX509.Verify(RSA)",
                                                dsX509.Verify(data, sign).ToString());

                // 鍵の相互変換
                jwk = RsaPublicKeyConverter.ParamToJwk(
                    ((RSA)dsX509.AsymmetricAlgorithm).ExportParameters(false));

                WriteLine.OutPutDebugAndConsole("RSA JWK", jwk);

                dsParam = new DigitalSignParam(
                    RsaPublicKeyConverter.JwkToParam(jwk),
                    EnumDigitalSignAlgorithm.RsaCSP_SHA256);

                WriteLine.OutPutDebugAndConsole("DigitalSignX509.Verify(RSA JWK)",
                                                dsParam.Verify(data, sign).ToString());
                #endregion

                #region DSA
                dsParam = new DigitalSignParam(EnumDigitalSignAlgorithm.DsaOpenSsl_SHA1);
                sign    = dsParam.Sign(data);
                WriteLine.OutPutDebugAndConsole(
                    "DigitalSignParam.Verify(DS1)",
                    dsParam.Verify(data, sign).ToString());

                dsXML = new DigitalSignXML(EnumDigitalSignAlgorithm.DsaOpenSsl_SHA1);
                sign  = dsXML.Sign(data);
                WriteLine.OutPutDebugAndConsole(
                    "DigitalSignXML.Verify(DS1)",
                    dsXML.Verify(data, sign).ToString());

                dsX509 = new DigitalSignX509(@"SHA256DSA.pfx", "test", "SHA256");
                sign   = dsX509.Sign(data);
                WriteLine.OutPutDebugAndConsole(
                    "DigitalSignX509.Verify(DSA)",
                    dsX509.Verify(data, sign).ToString());
                #endregion

                #region ECDSA
                // .NET Core on Linux
                DigitalSignECDsaX509 ecDsX509 = new DigitalSignECDsaX509(
                    @"SHA256ECDSA.pfx", "test", HashAlgorithmName.SHA256);

                sign = ecDsX509.Sign(data);
                WriteLine.OutPutDebugAndConsole(
                    "DigitalSignX509.Verify(ECDSA)",
                    ecDsX509.Verify(data, sign).ToString());

                token = "";
                token = JWT.Encode(payload, ((ECDsa)ecDsX509.AsymmetricAlgorithm), JwsAlgorithm.ES256);

                // 鍵の相互変換
                jwk = EccPublicKeyConverter.ParamToJwk(
                    ((ECDsa)ecDsX509.AsymmetricAlgorithm).ExportParameters(false));

                WriteLine.OutPutDebugAndConsole("ECDSA JWK", jwk);

                DigitalSignECDsaOpenSsl ecDsParam =
                    new DigitalSignECDsaOpenSsl(
                        EccPublicKeyConverter.JwkToParam(jwk),
                        HashAlgorithmCmnFunc.GetHashAlgorithmFromNameString(HashNameConst.SHA256));

                WriteLine.OutPutDebugAndConsole(
                    "DigitalSignX509.Verify(ECDSA JWK)",
                    ecDsParam.Verify(data, sign).ToString());

                Program.VerifyResult("JwsAlgorithm.ES256", token, ecDsParam.AsymmetricAlgorithm);

                #endregion

                #endregion

                WriteLine.OutPutDebugAndConsole("----------------------------------------------------------------------------------------------------");

                #region Test of the jose-jwt

                #region JWT

                #region Unsecured JWT
                // Creating Plaintext (unprotected) Tokens
                // https://github.com/dvsekhvalnov/jose-jwt#creating-plaintext-unprotected-tokens
                token = "";
                token = JWT.Encode(payload, null, JwsAlgorithm.none);
                WriteLine.OutPutDebugAndConsole("JwsAlgorithm.none", token);
                #endregion

                #region JWS (Creating signed Tokens)
                // https://github.com/dvsekhvalnov/jose-jwt#creating-signed-tokens

                #region HS-* family
                // HS256, HS384, HS512
                // https://github.com/dvsekhvalnov/jose-jwt#hs--family
                secretKey = new byte[] { 164, 60, 194, 0, 161, 189, 41, 38, 130, 89, 141, 164, 45, 170, 159, 209, 69, 137, 243, 216, 191, 131, 47, 250, 32, 107, 231, 117, 37, 158, 225, 234 };
                token     = "";
                token     = JWT.Encode(payload, secretKey, JwsAlgorithm.HS256);
                Program.VerifyResult("JwsAlgorithm.HS256", token, secretKey);
                #endregion

                #region RS-* and PS-* family
                // RS256, RS384, RS512 and PS256, PS384, PS512
                // https://github.com/dvsekhvalnov/jose-jwt#rs--and-ps--family
                // X509Certificate2 x509Certificate2 = new X509Certificate2();

                privateX509Path = @"SHA256RSA.pfx";
                publicX509Path  = @"SHA256RSA.cer";
                privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KSF);
                publicX509Key   = new X509Certificate2(publicX509Path, "", x509KSF);

                token = "";

                rsa   = (RSA)privateX509Key.PrivateKey;
                token = JWT.Encode(payload, rsa, JwsAlgorithm.RS256);
                Program.VerifyResult("JwsAlgorithm.RS256", token, rsa);

                #endregion

                #region ES- * family
                // ES256, ES384, ES512 ECDSA signatures
                // https://github.com/dvsekhvalnov/jose-jwt#es---family

                x = new byte[] { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
                y = new byte[] { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
                d = new byte[] { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 };

                eCParameters = new ECParameters();

                // Curve
                eCParameters.Curve =
                    EccPublicKeyConverter.GetECCurveFromCrvString(
                        EccPublicKeyConverter.GetCrvStringFromXCoordinate(x));

                // x, y, d
                eCParameters.Q.X = x;
                eCParameters.Q.Y = y;
                eCParameters.D   = d;
                ECDsaOpenSsl eCDsaOpenSsl = new ECDsaOpenSsl(eCParameters.Curve);
                eCDsaOpenSsl.ImportParameters(eCParameters);

                token = "";
                token = JWT.Encode(payload, eCDsaOpenSsl, JwsAlgorithm.ES256);
                Program.VerifyResult("JwsAlgorithm.ES256", token, eCDsaOpenSsl);

                try
                {
                    privateX509Path = @"SHA256ECDSA.pfx";
                    publicX509Path  = @"SHA256ECDSA.cer";
                    privateX509Key  = new X509Certificate2(privateX509Path, "test");
                    publicX509Key   = new X509Certificate2(publicX509Path, "");

                    // ECCurveを分析してみる。
                    ECCurve eCCurve = ((ECDsaOpenSsl)privateX509Key.GetECDsaPrivateKey()).ExportExplicitParameters(true).Curve;
                    WriteLine.OutPutDebugAndConsole("Inspect ECCurve", ObjectInspector.Inspect(eCCurve));

                    token = "";
                    token = JWT.Encode(payload, privateX509Key.GetECDsaPrivateKey(), JwsAlgorithm.ES256);
                    Program.VerifyResult("JwsAlgorithm.ES256", token, publicX509Key.GetECDsaPublicKey());
                }
                catch (Exception ex)
                {
                    WriteLine.OutPutDebugAndConsole("JwsAlgorithm.ES256", ex.GetType().ToString() + ", " + ex.Message);
                }

                #endregion

                #endregion

                #region JWE (Creating encrypted Tokens)
                // https://github.com/dvsekhvalnov/jose-jwt#creating-encrypted-tokens

                #region RSA-* key management family of algorithms
                // RSA-OAEP-256, RSA-OAEP and RSA1_5 key
                // https://github.com/dvsekhvalnov/jose-jwt#rsa--key-management-family-of-algorithms

                privateX509Path = @"SHA256RSA.pfx";
                publicX509Path  = @"SHA256RSA.cer";
                privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KSF);
                publicX509Key   = new X509Certificate2(publicX509Path, "", x509KSF);

                // RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256
                token = "";
                token = JWT.Encode(payload, publicX509Key.PublicKey.Key, JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256);
                Program.VerifyResult("JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256", token, privateX509Key.PrivateKey);

                // RSAES-OAEP and AES GCM
                try
                {
                    token = "";
                    token = JWT.Encode(payload, publicX509Key.PublicKey.Key, JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM);
                    Program.VerifyResult("JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM", token, privateX509Key.PrivateKey);
                }
                catch (Exception ex)
                {
                    // Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll' at ubunntu
                    WriteLine.OutPutDebugAndConsole("JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM", ex.GetType().ToString() + ", " + ex.Message);
                }
                #endregion

                #region Other key management family of algorithms

                secretKey = new byte[] { 164, 60, 194, 0, 161, 189, 41, 38, 130, 89, 141, 164, 45, 170, 159, 209, 69, 137, 243, 216, 191, 131, 47, 250, 32, 107, 231, 117, 37, 158, 225, 234 };

                #region DIR direct pre-shared symmetric key family of algorithms
                // https://github.com/dvsekhvalnov/jose-jwt#dir-direct-pre-shared-symmetric-key-family-of-algorithms
                token = "";
                token = JWT.Encode(payload, secretKey, JweAlgorithm.DIR, JweEncryption.A128CBC_HS256);
                Program.VerifyResult("JweAlgorithm.DIR, JweEncryption.A128CBC_HS256", token, secretKey);
                #endregion

                #region AES Key Wrap key management family of algorithms
                // AES128KW, AES192KW and AES256KW key management
                // https://github.com/dvsekhvalnov/jose-jwt#aes-key-wrap-key-management-family-of-algorithms
                token = "";
                token = JWT.Encode(payload, secretKey, JweAlgorithm.A256KW, JweEncryption.A256CBC_HS512);
                Program.VerifyResult("JweAlgorithm.A256KW, JweEncryption.A256CBC_HS512", token, secretKey);
                #endregion

                #region AES GCM Key Wrap key management family of algorithms
                // AES128GCMKW, AES192GCMKW and AES256GCMKW key management
                // https://github.com/dvsekhvalnov/jose-jwt#aes-gcm-key-wrap-key-management-family-of-algorithms
                try
                {
                    token = "";
                    token = JWT.Encode(payload, secretKey, JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512);
                    Program.VerifyResult("JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512", token, secretKey);
                }
                catch (Exception ex)
                {
                    // Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll' at ubunntu
                    WriteLine.OutPutDebugAndConsole("JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512", ex.GetType().ToString() + ", " + ex.Message);
                }
                #endregion

                #region ECDH-ES and ECDH-ES with AES Key Wrap key management family of algorithms
                // ECDH-ES and ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW key management
                // https://github.com/dvsekhvalnov/jose-jwt#ecdh-es-and-ecdh-es-with-aes-key-wrap-key-management-family-of-algorithms
                try
                {
                    x = new byte[] { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
                    y = new byte[] { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
                    publicKeyOfCng = EccKey.New(x, y, usage: CngKeyUsages.KeyAgreement);
                    token          = "";
                    token          = JWT.Encode(payload, publicKeyOfCng, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM);
                    Program.VerifyResult("JweAlgorithm.ECDH_ES, JweEncryption.A256GCM", token, publicKeyOfCng);
                }
                catch (Exception ex)
                {
                    // System.NotImplementedException: 'not yet'
                    WriteLine.OutPutDebugAndConsole("JweAlgorithm.ECDH_ES, JweEncryption.A256GCM", ex.GetType().ToString() + ", " + ex.Message);
                }
                #endregion

                #region PBES2 using HMAC SHA with AES Key Wrap key management family of algorithms
                token = "";
                token = JWT.Encode(payload, "top secret", JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512);
                Program.VerifyResult("JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512", token, "top secret");
                #endregion

                #endregion

                #endregion

                #endregion

                #endregion
            }
            catch (Exception ex)
            {
                WriteLine.OutPutDebugAndConsole(ex.ToString());
            }
        }
Пример #18
0
        static void Main(string[] args)
        {
            #region Variables

            OperatingSystem     os     = Environment.OSVersion;
            X509KeyStorageFlags x509KS = X509KeyStorageFlags.DefaultKeySet;

            string token = "";
            IDictionary <string, object> headers = null;
            IDictionary <string, object> payload = null;
            payload = new Dictionary <string, object>()
            {
                { "sub", "*****@*****.**" },
                { "exp", 1300819380 }
            };

            #region Keys
            byte[] secretKey = null;
            byte[] x         = null;
            byte[] y         = null;
            byte[] d         = null;

            string           privateX509Path = "";
            string           publicX509Path  = "";
            X509Certificate2 publicX509Key   = null;
            X509Certificate2 privateX509Key  = null;

            CngKey publicKeyOfCng  = null;
            CngKey privateKeyOfCng = null;
            #endregion

            #endregion

            #region Certificates

            #region RSA
            privateX509Path = @"SHA256RSA.pfx";
            publicX509Path  = @"SHA256RSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KS);
            publicX509Key   = new X509Certificate2(publicX509Path, "", x509KS);
            Program.PrivateX509KeyInspector("RSA", privateX509Key);
            Program.PublicX509KeyInspector("RSA", publicX509Key);
            #endregion

            #region DSA
            // https://github.com/dotnet/corefx/issues/18733#issuecomment-296723615
            privateX509Path = @"SHA256DSA.pfx";
            publicX509Path  = @"SHA256DSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test");
            publicX509Key   = new X509Certificate2(publicX509Path, "");
            Program.PrivateX509KeyInspector("DSA", privateX509Key);
            Program.PublicX509KeyInspector("DSA", publicX509Key);
            DSA privateDSA = privateX509Key.GetDSAPrivateKey();
            Program.MyWriteLine("privateDSA: " + (privateDSA == null ? "is null" : "is not null"));
            DSA publicDSA = null; // publicX509Key.GetDSAPublicKey(); // Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException
            #endregion

            #region ECDsa
            // https://github.com/dotnet/corefx/issues/18733#issuecomment-296723615
            privateX509Path = @"SHA256ECDSA.pfx";
            publicX509Path  = @"SHA256ECDSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test");
            publicX509Key   = new X509Certificate2(publicX509Path, "");
            Program.PrivateX509KeyInspector("ECDsa", privateX509Key);
            Program.PublicX509KeyInspector("ECDsa", publicX509Key);
            ECDsa privateECDsa = privateX509Key.GetECDsaPrivateKey();
            Program.MyWriteLine("privateECDsa: " + (privateECDsa == null ? "is null" : "is not null"));
            ECDsa publicECDsa = publicX509Key.GetECDsaPublicKey();
            Program.MyWriteLine("publicECDsa: " + (publicECDsa == null ? "is null" : "is not null"));
            #endregion

            #endregion

            Program.MyWriteLine("----------------------------------------------------------------------------------------------------");

            #region JWT

            #region Unsecured JWT
            // Creating Plaintext (unprotected) Tokens
            // https://github.com/dvsekhvalnov/jose-jwt#creating-plaintext-unprotected-tokens
            token = "";
            token = JWT.Encode(payload, null, JwsAlgorithm.none);
            Program.MyWriteLine("JwsAlgorithm.none: " + token);
            #endregion

            #region JWS (Creating signed Tokens)
            // https://github.com/dvsekhvalnov/jose-jwt#creating-signed-tokens

            #region HS-* family
            // HS256, HS384, HS512
            // https://github.com/dvsekhvalnov/jose-jwt#hs--family
            secretKey = new byte[] { 164, 60, 194, 0, 161, 189, 41, 38, 130, 89, 141, 164, 45, 170, 159, 209, 69, 137, 243, 216, 191, 131, 47, 250, 32, 107, 231, 117, 37, 158, 225, 234 };
            token     = "";
            token     = JWT.Encode(payload, secretKey, JwsAlgorithm.HS256);
            Program.VerifyResult("JwsAlgorithm.HS256: ", token, secretKey);
            #endregion

            #region RS-* and PS-* family
            // RS256, RS384, RS512 and PS256, PS384, PS512
            // https://github.com/dvsekhvalnov/jose-jwt#rs--and-ps--family
            // X509Certificate2 x509Certificate2 = new X509Certificate2();

            privateX509Path = @"SHA256RSA.pfx";
            publicX509Path  = @"SHA256RSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KS);
            publicX509Key   = new X509Certificate2(publicX509Path, "", x509KS);

            token = "";
            token = JWT.Encode(payload, privateX509Key.PrivateKey, JwsAlgorithm.RS256);
            Program.VerifyResult("JwsAlgorithm.RS256: ", token, publicX509Key.PublicKey.Key);
            #endregion

            #region ES- * family
            // ES256, ES384, ES512 ECDSA signatures
            // https://github.com/dvsekhvalnov/jose-jwt#es---family

            x = new byte[] { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
            y = new byte[] { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
            d = new byte[] { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 };

            if (os.Platform == PlatformID.Win32NT)
            {
                // https://github.com/dvsekhvalnov/jose-jwt/blob/master/jose-jwt/Security/Cryptography/EccKey.cs
                privateKeyOfCng = EccKey.New(x, y, d);
                publicKeyOfCng  = EccKey.New(x, y);

                token = "";
                token = JWT.Encode(payload, privateKeyOfCng, JwsAlgorithm.ES256);
                Program.VerifyResult("JwsAlgorithm.ES256: ", token, publicKeyOfCng);
            }
            else // == PlatformID.Unix
            {
                // (x, y, d)を使用して、ECCurveからECDsaOpenSslを生成できれば...。

                //ECCurve eCCurve = new ECCurve();
                ////eCCurve.A = x;
                ////eCCurve.B = y;
                ////ECDsaOpenSsl ecd = new ECDsaOpenSsl(eCCurve);
                ////eCCurve = ecd.ExportExplicitParameters(true).Curve;

                //token = "";
                //token = JWT.Encode(payload, new ECDsaOpenSsl(eCCurve), JwsAlgorithm.ES256);
                //Program.VerifyResult("JwsAlgorithm.ES256: ", token, new ECDsaOpenSsl(eCCurve));
            }

            privateX509Path = @"SHA256ECDSA.pfx";
            publicX509Path  = @"SHA256ECDSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test");
            publicX509Key   = new X509Certificate2(publicX509Path, "");

            try
            {
                if (os.Platform == PlatformID.Unix)
                {
                    // ECCurveを分析してみる。
                    ECCurve eCCurve = ((ECDsaOpenSsl)privateX509Key.GetECDsaPrivateKey()).ExportExplicitParameters(true).Curve;
                    Program.MyWriteLine("Inspect ECCurve: " + ObjectInspector.Inspect(eCCurve));
                }

                token = "";
                token = JWT.Encode(payload, privateX509Key.GetECDsaPrivateKey(), JwsAlgorithm.ES256);
                Program.VerifyResult("JwsAlgorithm.ES256: ", token, publicX509Key.GetECDsaPublicKey());
            }
            catch (Exception ex)
            {
                Program.MyWriteLine("JwsAlgorithm.ES256: " + ex.GetType().ToString() + ", " + ex.Message);
            }

            #endregion

            #endregion

            #region JWE (Creating encrypted Tokens)
            // https://github.com/dvsekhvalnov/jose-jwt#creating-encrypted-tokens

            #region RSA-* key management family of algorithms
            // RSA-OAEP-256, RSA-OAEP and RSA1_5 key
            // https://github.com/dvsekhvalnov/jose-jwt#rsa--key-management-family-of-algorithms

            privateX509Path = @"SHA256RSA.pfx";
            publicX509Path  = @"SHA256RSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KS);
            publicX509Key   = new X509Certificate2(publicX509Path, "", x509KS);

            // RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256
            token = "";
            token = JWT.Encode(payload, publicX509Key.PublicKey.Key, JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256);
            Program.VerifyResult("JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256: ", token, privateX509Key.PrivateKey);

            // RSAES-OAEP and AES GCM
            try
            {
                token = "";
                token = JWT.Encode(payload, publicX509Key.PublicKey.Key, JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM);
                Program.VerifyResult("JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM: ", token, privateX509Key.PrivateKey);
            }
            catch (Exception ex)
            {
                // Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll' at ubunntu
                Program.MyWriteLine("JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM: " + ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region Other key management family of algorithms

            secretKey = new byte[] { 164, 60, 194, 0, 161, 189, 41, 38, 130, 89, 141, 164, 45, 170, 159, 209, 69, 137, 243, 216, 191, 131, 47, 250, 32, 107, 231, 117, 37, 158, 225, 234 };

            #region DIR direct pre-shared symmetric key family of algorithms
            // https://github.com/dvsekhvalnov/jose-jwt#dir-direct-pre-shared-symmetric-key-family-of-algorithms
            token = "";
            token = JWT.Encode(payload, secretKey, JweAlgorithm.DIR, JweEncryption.A128CBC_HS256);
            Program.VerifyResult("JweAlgorithm.DIR, JweEncryption.A128CBC_HS256: ", token, secretKey);
            #endregion

            #region AES Key Wrap key management family of algorithms
            // AES128KW, AES192KW and AES256KW key management
            // https://github.com/dvsekhvalnov/jose-jwt#aes-key-wrap-key-management-family-of-algorithms
            token = "";
            token = JWT.Encode(payload, secretKey, JweAlgorithm.A256KW, JweEncryption.A256CBC_HS512);
            Program.VerifyResult("JweAlgorithm.A256KW, JweEncryption.A256CBC_HS512: ", token, secretKey);
            #endregion

            #region AES GCM Key Wrap key management family of algorithms
            // AES128GCMKW, AES192GCMKW and AES256GCMKW key management
            // https://github.com/dvsekhvalnov/jose-jwt#aes-gcm-key-wrap-key-management-family-of-algorithms
            try
            {
                token = "";
                token = JWT.Encode(payload, secretKey, JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512);
                Program.VerifyResult("JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512: ", token, secretKey);
            }
            catch (Exception ex)
            {
                // Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll' at ubunntu
                Program.MyWriteLine("JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512: " + ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region ECDH-ES and ECDH-ES with AES Key Wrap key management family of algorithms
            // ECDH-ES and ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW key management
            // https://github.com/dvsekhvalnov/jose-jwt#ecdh-es-and-ecdh-es-with-aes-key-wrap-key-management-family-of-algorithms
            try
            {
                x = new byte[] { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
                y = new byte[] { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
                publicKeyOfCng = EccKey.New(x, y, usage: CngKeyUsages.KeyAgreement);
                token          = "";
                token          = JWT.Encode(payload, publicKeyOfCng, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM);
                Program.VerifyResult("JweAlgorithm.ECDH_ES, JweEncryption.A256GCM: ", token, publicKeyOfCng);
            }
            catch (Exception ex)
            {
                // System.NotImplementedException: 'not yet'
                Program.MyWriteLine("JweAlgorithm.ECDH_ES, JweEncryption.A256GCM: " + ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region PBES2 using HMAC SHA with AES Key Wrap key management family of algorithms
            token = "";
            token = JWT.Encode(payload, "top secret", JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512);
            Program.VerifyResult("JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512: ", token, "top secret");
            #endregion

            #endregion

            #endregion

            #endregion

            Program.MyWriteLine("----------------------------------------------------------------------------------------------------");

            #region ELSE

            #region Additional utilities
            // https://github.com/dvsekhvalnov/jose-jwt#additional-utilities

            #region Adding extra headers
            // https://github.com/dvsekhvalnov/jose-jwt#adding-extra-headers

            headers = new Dictionary <string, object>()
            {
                { "typ", "JWT" },
                { "cty", "JWT" },
                { "keyid", "111-222-333" }
            };

            privateX509Path = @"SHA256RSA.pfx";
            publicX509Path  = @"SHA256RSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KS);
            publicX509Key   = new X509Certificate2(publicX509Path, "", x509KS);

            token = "";
            token = JWT.Encode(payload, privateX509Key.PrivateKey, JwsAlgorithm.RS256, extraHeaders: headers);
            Program.VerifyResult("Adding extra headers to RS256: ", token, privateX509Key.PrivateKey);
            #endregion

            #region Strict validation
            // https://github.com/dvsekhvalnov/jose-jwt#strict-validation
            // 厳密な検証では、Algorithmを指定可能
            Program.MyWriteLine("Strict validation(RS256): " + JWT.Decode(token, privateX509Key.PrivateKey, JwsAlgorithm.RS256));
            #endregion

            #region Two-phase validation
            // https://github.com/dvsekhvalnov/jose-jwt#two-phase-validation
            // ヘッダのkeyidクレームからキーを取り出して復号化する方法。
            //headers = JWT.Headers(token);
            // ・・・
            //string hoge = JWT.Decode(token, "key");
            #endregion

            #region Working with binary payload
            // https://github.com/dvsekhvalnov/jose-jwt#working-with-binary-payload
            #endregion

            #endregion

            #region Settings
            // https://github.com/dvsekhvalnov/jose-jwt#settings
            // グローバル設定

            #region Example of JWTSettings
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-jwtsettings

            #endregion

            #region Customizing json <-> object parsing & mapping
            // https://github.com/dvsekhvalnov/jose-jwt#customizing-json---object-parsing--mapping
            // マッピング
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-newtonsoftjson-mapper
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-servicestack-mapper

            #endregion

            #region Customizing algorithm implementations
            // https://github.com/dvsekhvalnov/jose-jwt#customizing-algorithm-implementations
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-custom-algorithm-implementation
            #endregion

            #region Providing aliases
            // https://github.com/dvsekhvalnov/jose-jwt#providing-aliases
            #endregion

            #endregion

            #region Dealing with keys
            // https://github.com/dvsekhvalnov/jose-jwt#dealing-with-keys
            // https://github.com/dvsekhvalnov/jose-jwt#rsacryptoserviceprovider
            // - http://stackoverflow.com/questions/7444586/how-can-i-sign-a-file-using-rsa-and-sha256-with-net
            // - http://hintdesk.com/c-how-to-fix-invalid-algorithm-specified-when-signing-with-sha256/
            // https://github.com/dvsekhvalnov/jose-jwt#if-you-have-only-rsa-private-key
            // - http://www.donaldsbaconbytes.com/2016/08/create-jwt-with-a-private-rsa-key/
            #endregion

            #region Strong-Named assembly
            // https://github.com/dvsekhvalnov/jose-jwt#strong-named-assembly
            // - https://github.com/dvsekhvalnov/jose-jwt/issues/5
            // - https://github.com/brutaldev/StrongNameSigner
            #endregion

            #region More examples
            // https://github.com/dvsekhvalnov/jose-jwt#more-examples
            // https://github.com/dvsekhvalnov/jose-jwt/blob/master/UnitTests/TestSuite.cs
            #endregion

            #endregion

            Console.ReadKey();
        }
        /// <summary>
        /// Encrypt Async
        /// </summary>
        /// <param name="value">The value to encrypt as JWE string</param>
        /// <returns>JWE string</returns>
        public async Task <string> EncryptAsync(string value)
        {
            JsonWebKey publicJsonWebKey = null;

            try
            {
                publicJsonWebKey = await this.keyResolver.GetEncryptionKeyAsync();

                if (publicJsonWebKey == null)
                {
                    throw new EncryptionException(string.Format("Encryption key not found by KeyResolver."));
                }

                var encodedJwe   = string.Empty;
                var extraHeaders = new Dictionary <string, object>
                {
                    { "kid", publicJsonWebKey.Kid },
                    { "kty", publicJsonWebKey.Kty }
                };
                if (publicJsonWebKey.Kty == "EC")
                {
                    var xByteArray = Jose.Base64Url.Decode(publicJsonWebKey.X);
                    var yByteArray = Jose.Base64Url.Decode(publicJsonWebKey.Y);
                    var eccKey     = EccKey.New(xByteArray, yByteArray, null, CngKeyUsages.KeyAgreement);
                    encodedJwe = Jose.JWT.Encode(value, eccKey, Jose.JweAlgorithm.ECDH_ES_A256KW, Jose.JweEncryption.A256GCM, null, extraHeaders, null);
                }
                else if (publicJsonWebKey.Kty == "RSA")
                {
                    var keyParams = new RSAParameters
                    {
                        Exponent = Jose.Base64Url.Decode(publicJsonWebKey.E),
                        Modulus  = Jose.Base64Url.Decode(publicJsonWebKey.N)
                    };
                    var rsa = RSA.Create();
                    rsa.ImportParameters(keyParams);
                    encodedJwe = Jose.JWT.Encode(value, rsa, Jose.JweAlgorithm.RSA_OAEP_256, Jose.JweEncryption.A256GCM, null, extraHeaders, null);
                }
                else
                {
                    throw new EncryptionException("Unsupport Json Web Key type.");
                }

                logger.LogDebug("Encrypting data with keyid: {0}, type: {1}", publicJsonWebKey.Kid, publicJsonWebKey.Kty);

                return(Constants.CIPHER_HEADER + encodedJwe);
            }
            catch (Jose.EncryptionException iaEx)
            {
                if (publicJsonWebKey == null)
                {
                    logger.LogError(iaEx, "An Encryption Exceptionn occurred.");
                }
                else
                {
                    logger.LogError(iaEx, "An Encryption Exceptionn occurred. keyid: {0}, type: {1}", publicJsonWebKey.Kid, publicJsonWebKey.Kty);
                }

                throw new EncryptionException("Unable to decrypt data.", iaEx);
            }
            catch (Jose.InvalidAlgorithmException iaEx)
            {
                if (publicJsonWebKey == null)
                {
                    logger.LogError(iaEx, "An Invalid Algorithm Exception occurred.");
                }
                else
                {
                    logger.LogError(iaEx, "An Invalid Algorithm Exception occurred. keyid: {0}, type: {1}", publicJsonWebKey.Kid, publicJsonWebKey.Kty);
                }

                throw new EncryptionException("Unable to decrypt data.", iaEx);
            }
            catch (EncryptionException eeEx)
            {
                if (publicJsonWebKey == null)
                {
                    logger.LogError(eeEx, "An Encryption Exception Occurred: Value: {0}", value);
                }
                else
                {
                    logger.LogError(eeEx, "An Encryption Exception Occurred: Keyid: {0}, type: {1}", publicJsonWebKey.Kid, publicJsonWebKey.Kty);
                }

                throw;
            }
            catch (Exception ex)
            {
                if (ex.GetType() == typeof(NotImplementedException))
                {
                    throw;
                }
                else
                {
                    logger.LogError(ex, "An Exception Occurred: Keyid: {0}, type: {1}", publicJsonWebKey.Kid, publicJsonWebKey.Kty);
                    throw new EncryptionException("Unable to encrypt data.", ex);
                }
            }
        }
        /// <summary>
        /// Decrypt Async
        /// </summary>
        /// <param name="cipher">Cipher string</param>
        /// <returns>Descrypted string</returns>
        public async Task <string> DecryptAsync(string cipher)
        {
            var privateJsonWebKey = default(JsonWebKey);

            try
            {
                if (string.IsNullOrEmpty(cipher) ||
                    !cipher.StartsWith(Constants.CIPHER_HEADER, StringComparison.Ordinal))
                {
                    throw new InvalidHeaderException("Invalid encryption header.");
                }

                var value = default(string);
                var requestedprivateJsonWebKey = default(JsonWebKey);
                try
                {
                    cipher = cipher.Substring(Constants.CIPHER_HEADER.Length);
                    var cipherArray = cipher.Split(new char[] { '.' });
                    var json        = Encoding.UTF8.GetString(Jose.Base64Url.Decode(cipherArray[0]));
                    requestedprivateJsonWebKey = new JsonWebKey(json);
                }
                catch (ArgumentNullException anEx)
                {
                    throw new SerializerException("Unable to deserializer value.", anEx);
                }
                catch (ArgumentException aEx)
                {
                    throw new SerializerException("Unable to deserializer value.", aEx);
                }

                privateJsonWebKey = await this.keyResolver.GetDecryptionKeyAsync(requestedprivateJsonWebKey.Kid);

                if (privateJsonWebKey == null)
                {
                    throw new EncryptionException(string.Format("Decryption key not found. ID: '{0}'.", requestedprivateJsonWebKey.Kid));
                }

                if (privateJsonWebKey.Kty == "EC")
                {
                    var xByteArray = Jose.Base64Url.Decode(privateJsonWebKey.X);
                    var yByteArray = Jose.Base64Url.Decode(privateJsonWebKey.Y);
                    var dByteArray = Jose.Base64Url.Decode(privateJsonWebKey.D);
                    var privateKey = EccKey.New(xByteArray, yByteArray, dByteArray, CngKeyUsages.KeyAgreement);
                    value = Jose.JWT.Decode(cipher, privateKey);
                }
                else if (privateJsonWebKey.Kty == "RSA")
                {
                    var keyParams = new RSAParameters
                    {
                        Exponent = Jose.Base64Url.Decode(privateJsonWebKey.E),
                        Modulus  = Jose.Base64Url.Decode(privateJsonWebKey.N),
                        P        = Jose.Base64Url.Decode(privateJsonWebKey.P),
                        Q        = Jose.Base64Url.Decode(privateJsonWebKey.Q),
                        D        = Jose.Base64Url.Decode(privateJsonWebKey.D),
                        InverseQ = Jose.Base64Url.Decode(privateJsonWebKey.QI),
                        DP       = Jose.Base64Url.Decode(privateJsonWebKey.DQ),
                        DQ       = Jose.Base64Url.Decode(privateJsonWebKey.DP)
                    };

                    var rsa = RSA.Create();
                    rsa.ImportParameters(keyParams);
                    value = Jose.JWT.Decode(cipher, rsa, Jose.JweAlgorithm.RSA_OAEP_256, Jose.JweEncryption.A256GCM);
                }
                else
                {
                    throw new EncryptionException("Unsupport Json Web Key type.");
                }

                logger.LogDebug("Decrypted data with keyid: {0}, type: {1}, value: {2}", privateJsonWebKey.Kid, privateJsonWebKey.Kty, value);

                return(value);
            }
            catch (Jose.EncryptionException iaEx)
            {
                if (privateJsonWebKey == null)
                {
                    logger.LogError(iaEx, "An Encryption Exceptionn occurred.");
                }
                else
                {
                    logger.LogError(iaEx, "An Encryption Exceptionn occurred. keyid: {0}, type: {1}", privateJsonWebKey.Kid, privateJsonWebKey.Kty);
                }

                throw new EncryptionException("Unable to decrypt data.", iaEx);
            }
            catch (Jose.InvalidAlgorithmException iaEx)
            {
                if (privateJsonWebKey == null)
                {
                    logger.LogError(iaEx, "An Invalid Algorithm Exception occurred.");
                }
                else
                {
                    logger.LogError(iaEx, "An Invalid Algorithm Exception occurred. keyid: {0}, type: {1}", privateJsonWebKey.Kid, privateJsonWebKey.Kty);
                }

                throw new EncryptionException("Unable to decrypt data.", iaEx);
            }
            catch (InvalidHeaderException ihEx)
            {
                if (privateJsonWebKey == null)
                {
                    logger.LogError(ihEx, "An Invalid Header Exception occurred.");
                }
                else
                {
                    logger.LogError(ihEx, "An Invalid Header Exception occurred. keyid: {0}, type: {1}", privateJsonWebKey.Kid, privateJsonWebKey.Kty);
                }

                throw;
            }
            catch (SerializerException sEx)
            {
                if (privateJsonWebKey == null)
                {
                    logger.LogError(sEx.InnerException, "Unable to deserializer value.");
                }
                else
                {
                    logger.LogError(sEx, "Unable to deserializer value.: Keyid: {0}, type: {1}", privateJsonWebKey.Kid, privateJsonWebKey.Kty);
                }

                throw;
            }
            catch (EncryptionException eEx)
            {
                if (privateJsonWebKey == null)
                {
                    logger.LogError(eEx, "An Decryption Exception Occurred");
                }
                else
                {
                    logger.LogError(eEx, "An Decryption Exception Occurred: Keyid: {0}, type: {1}", privateJsonWebKey.Kid, privateJsonWebKey.Kty);
                }

                throw;
            }
            catch (Exception ex)
            {
                if (privateJsonWebKey == null)
                {
                    logger.LogError(ex, "An Decryption Exception Occurred");
                }
                else
                {
                    logger.LogError(ex, "An Exception Occurred: Keyid: {0}, type: {1}", privateJsonWebKey.Kid, privateJsonWebKey.Kty);
                }

                throw new EncryptionException("Unable to decrypt data.", ex);
            }
        }