예제 #1
0
        /// <summary>CreateByECDsa</summary>
        /// <param name="iss">client_id</param>
        /// <param name="aud">Token2 EndPointのuri</param>
        /// <param name="forExp">DateTimeOffset</param>
        /// <param name="scopes">scopes</param>
        /// <param name="ecdsaX509FilePath">ES256用の X.509秘密鍵 の File Path</param>
        /// <param name="ecdsaX509Password">ES256用の X.509秘密鍵 の Password</param>
        /// <returns>JwtAssertion</returns>
        public static string CreateByECDsa(
            string iss, string aud, TimeSpan forExp, string scopes,
            string ecdsaX509FilePath, string ecdsaX509Password)
        ///// <param name="eccPrivateKey">ES256用のECParameters秘密鍵</param>
        //ECParameters ecPrivateKey) // ECDsa.ExportParameters(true)が動かねぇ。
        {
            string json = "";

            //string jws = "";

            #region ClaimSetの生成

            Dictionary <string, object> jwtAssertionClaimSet = new Dictionary <string, object>();

            jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.iss, iss); // client_id
            jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.aud, aud); // Token EndPointのuri。

            jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.exp, CmnJwtToken.CreateExpClaim(forExp));
            jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.iat, CmnJwtToken.CreateIatClaim());

            jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.jti, CmnJwtToken.CreateJitClaim());
            jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.scope, scopes); // scopes

            json = JsonConvert.SerializeObject(jwtAssertionClaimSet);

            #endregion

            #region JWT化

            JWS_ES256_X509 jwtES256 = new JWS_ES256_X509(ecdsaX509FilePath, ecdsaX509Password);
            return(jwtES256.Create(json));

            #endregion
        }
예제 #2
0
        // - OpenID Connect Client Initiated Backchannel Authentication Flow - Core 1.0 draft-01
        //   https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html
        // - Financial-grade API: Client Initiated Backchannel Authentication Profile
        //   https://openid.net/specs/openid-financial-api-ciba-ID1.html

        #region Create
        ///// <summary>CreateCiba</summary>
        ///// <param name="iss">string</param>
        ///// <param name="aud">string</param>
        ///// <param name="exp">string</param>
        ///// <param name="nbf">string</param>
        ///// <param name="scopes">string</param>
        ///// <param name="client_notification_token">string</param>
        ///// <param name="binding_message">string</param>
        ///// <param name="user_code">string</param>
        ///// <param name="requested_expiry">string</param>
        ///// <param name="login_hint">string</param>
        ///// <param name="requestContextAndIntent">Dictionary(string, object)</param>
        ///// <param name="jwkPrivateKey">ES256用のJWK秘密鍵</param>
        ///// <returns>RequestObject</returns>
        //public static string CreateCiba(
        //    string iss, string aud, string exp, string nbf, string scopes,
        //    string client_notification_token, string binding_message,
        //    string user_code, string requested_expiry, string login_hint,
        //    Dictionary<string, object> requestContextAndIntent, string jwkPrivateKey)
        //{
        //    EccPrivateKeyConverter epkc = new EccPrivateKeyConverter();
        //    return RequestObject.CreateCiba(
        //        iss, aud, exp, nbf, scopes,
        //        client_notification_token, binding_message,
        //        user_code, requested_expiry, login_hint,
        //        requestContextAndIntent, epkc.JwkToParam(jwkPrivateKey));
        //}

        /// <summary>CreateCiba</summary>
        /// <param name="iss">string</param>
        /// <param name="aud">string</param>
        /// <param name="exp">string</param>
        /// <param name="nbf">string</param>
        /// <param name="scopes">string</param>
        /// <param name="client_notification_token">string</param>
        /// <param name="binding_message">string</param>
        /// <param name="user_code">string</param>
        /// <param name="requested_expiry">string</param>
        /// <param name="login_hint">string</param>
        /// <param name="requestContextAndIntent">Dictionary(string, object)</param>
        /// <param name="ecdsaX509FilePath">ES256用の X.509秘密鍵 の File Path</param>
        /// <param name="ecdsaX509Password">ES256用の X.509秘密鍵 の Password</param>
        /// <returns>RequestObject</returns>
        public static string CreateCiba(
            string iss, string aud, string exp, string nbf, string scopes,
            string client_notification_token, string binding_message,
            string user_code, string requested_expiry, string login_hint,
            Dictionary <string, object> requestContextAndIntent,
            string ecdsaX509FilePath, string ecdsaX509Password)
        ///// <param name="ecPrivateKey">ES256用のECParameters秘密鍵</param>
        //ECParameters ecPrivateKey) // ECDsa.ExportParameters(true)が動かねぇ。
        {
            string json = "";

            #region ClaimSetの生成

            Dictionary <string, object> requestObjectClaimSet = new Dictionary <string, object>();

            requestObjectClaimSet.Add(OAuth2AndOIDCConst.iss, iss); // client_id
            requestObjectClaimSet.Add(OAuth2AndOIDCConst.aud, aud); // ROS EndPointのuri。
            requestObjectClaimSet.Add(OAuth2AndOIDCConst.exp, exp);
            requestObjectClaimSet.Add(OAuth2AndOIDCConst.iat, CmnJwtToken.CreateIatClaim());
            requestObjectClaimSet.Add(OAuth2AndOIDCConst.nbf, nbf);
            requestObjectClaimSet.Add(OAuth2AndOIDCConst.jti, CmnJwtToken.CreateJitClaim());

            requestObjectClaimSet.Add(OAuth2AndOIDCConst.scope, scopes);
            requestObjectClaimSet.Add(OAuth2AndOIDCConst.client_notification_token, client_notification_token);
            requestObjectClaimSet.Add(OAuth2AndOIDCConst.binding_message, binding_message);

            if (!string.IsNullOrEmpty(user_code))
            {
                requestObjectClaimSet.Add(OAuth2AndOIDCConst.user_code, user_code);
            }
            if (!string.IsNullOrEmpty(requested_expiry))
            {
                requestObjectClaimSet.Add(OAuth2AndOIDCConst.requested_expiry, requested_expiry);
            }

            requestObjectClaimSet.Add(OAuth2AndOIDCConst.login_hint, login_hint);

            if (requestContextAndIntent != null)
            {
                foreach (string key in requestContextAndIntent.Keys)
                {
                    requestObjectClaimSet.Add(key, requestContextAndIntent[key]);
                }
            }

            json = JsonConvert.SerializeObject(requestObjectClaimSet);

            #endregion

            #region JWT化

            JWS_ES256_X509 jwtES256 = new JWS_ES256_X509(ecdsaX509FilePath, ecdsaX509Password);
            return(jwtES256.Create(json));

            #endregion
        }
예제 #3
0
        /// <summary>汎用認証サイトの発行したJWT形式のTokenを検証する。</summary>
        /// <param name="jwtToken">JWT形式のToken</param>
        /// <param name="jwtPayload">
        /// JWS, JWS + JEWの場合があるのでペイロードを返す。
        /// </param>
        /// <returns>検証結果</returns>
        public static bool Verify(string jwtToken, out string jwtPayload)
        {
            jwtPayload = "";

            JWE jwe = null;
            JWS jws = null;

            // 復号化(JWEの場合)
            bool isJWE_FAPI2 = false;

            if (3 < jwtToken.Split('.').Length)
            {
                isJWE_FAPI2 = true;

                // ヘッダ
                JWE_Header jweHeader = JsonConvert.DeserializeObject <JWE_Header>(
                    CustomEncode.ByteToString(CustomEncode.FromBase64UrlString(jwtToken.Split('.')[0]), CustomEncode.UTF_8));

                if (jweHeader.alg == JwtConst.RSA_OAEP)
                {
                    jwe = new JWE_RsaOaepAesGcm_X509(
                        CmnClientParams.RsaPfxFilePath,
                        CmnClientParams.RsaPfxPassword);
                }
                else if (jweHeader.alg == JwtConst.RSA1_5)
                {
                    jwe = new JWE_Rsa15A128CbcHS256_X509(
                        CmnClientParams.RsaPfxFilePath,
                        CmnClientParams.RsaPfxPassword);
                }
                else
                {
                    throw new NotSupportedException(string.Format(
                                                        "This jwe alg of {0} is not supported.", jweHeader.alg));
                }

                jwe.Decrypt(jwtToken, out jwtToken);
            }
            else
            {
                isJWE_FAPI2 = false;
            }

            // 検証
            // ヘッダ
            JWS_Header jwsHeader = JsonConvert.DeserializeObject <JWS_Header>(
                CustomEncode.ByteToString(CustomEncode.FromBase64UrlString(jwtToken.Split('.')[0]), CustomEncode.UTF_8));

            if (jwsHeader.alg == JwtConst.ES256 && isJWE_FAPI2)
            {
            }                                                       // 正常
            else if (jwsHeader.alg == JwtConst.RS256 && !isJWE_FAPI2)
            {
            }                                                             // 正常
            else
            {
                throw new NotSupportedException("Unexpected combination of JWS and JWE.");
            }

            // 証明書を使用するか、Jwkを使用するか判定
            if (string.IsNullOrEmpty(jwsHeader.jku) ||
                string.IsNullOrEmpty(jwsHeader.kid))
            {
                // 旧バージョン(証明書を使用
                if (isJWE_FAPI2)
                {
#if NET45 || NET46
                    throw new NotSupportedException("FAPI2 is not supported in this dotnet version.");
#else
                    jws = new JWS_ES256_X509(CmnClientParams.EcdsaCerFilePath, "");
#endif
                }
                else
                {
                    jws = new JWS_RS256_X509(CmnClientParams.RsaCerFilePath, "");
                }
            }
            else
            {
                // 新バージョン(Jwkを使用
                if (string.IsNullOrEmpty(OAuth2AndOIDCParams.JwkSetFilePath))
                {
                    // jku(jwks_uri)使用のカバレッジ

                    // Client側
                    JObject jwkObject = JwkSetStore.GetInstance().GetJwkObject(jwsHeader.kid);

                    // チェック
                    if (jwkObject == null)
                    {
                        // 書込
                        jwkObject = JwkSetStore.GetInstance().SetJwkSetObject(jwsHeader.jku, jwsHeader.kid);
                    }

                    // チェック
                    if (jwkObject == null)
                    {
                        // 証明書を使用
                        if (isJWE_FAPI2)
                        {
#if NET45 || NET46
                            throw new NotSupportedException("FAPI2 is not supported in this dotnet version.");
#else
                            jws = new JWS_ES256_X509(CmnClientParams.EcdsaCerFilePath, "");
#endif
                        }
                        else
                        {
                            jws = new JWS_RS256_X509(CmnClientParams.RsaCerFilePath, "");
                        }
                    }
                    else
                    {
                        // Jwkを使用
                        if (isJWE_FAPI2)
                        {
#if NET45 || NET46
                            throw new NotSupportedException("FAPI2 is not supported in this dotnet version.");
#else
                            EccPublicKeyConverter epkc = new EccPublicKeyConverter();
                            jws = new JWS_ES256_Param(epkc.JwkToParam(jwkObject), false);
#endif
                        }
                        else
                        {
                            RsaPublicKeyConverter rpkc = new RsaPublicKeyConverter();
                            jws = new JWS_RS256_Param(rpkc.JwkToParam(jwkObject));
                        }
                    }
                }
                else
                {
                    // JwkSet使用のカバレッジ
                    // AuthZ側でClient側テストを行うためのカバレージ
                    JObject jwkObject = null;

                    if (ResourceLoader.Exists(OAuth2AndOIDCParams.JwkSetFilePath, false))
                    {
                        JwkSet jwkSet = JwkSet.LoadJwkSet(OAuth2AndOIDCParams.JwkSetFilePath);
                        jwkObject = JwkSet.GetJwkObject(jwkSet, jwsHeader.kid);
                    }

                    if (jwkObject == null)
                    {
                        // 証明書を使用
                        if (isJWE_FAPI2)
                        {
#if NET45 || NET46
                            throw new NotSupportedException("FAPI2 is not supported in this dotnet version.");
#else
                            jws = new JWS_ES256_X509(CmnClientParams.EcdsaCerFilePath, "");
#endif
                        }
                        else
                        {
                            jws = new JWS_RS256_X509(CmnClientParams.RsaCerFilePath, "");
                        }
                    }
                    else
                    {
                        // Jwkを使用
                        if (isJWE_FAPI2)
                        {
#if NET45 || NET46
                            throw new NotSupportedException("FAPI2 is not supported in this dotnet version.");
#else
                            EccPublicKeyConverter epkc = new EccPublicKeyConverter();
                            jws = new JWS_ES256_Param(epkc.JwkToParam(jwkObject), false);
#endif
                        }
                        else
                        {
                            RsaPublicKeyConverter rpkc = new RsaPublicKeyConverter();
                            jws = new JWS_RS256_Param(rpkc.JwkToParam(jwkObject));
                        }
                    }
                }
            }

            bool ret = jws.Verify(jwtToken);

            if (ret)
            {
                jwtPayload = CustomEncode.ByteToString(
                    CustomEncode.FromBase64UrlString(jwtToken.Split('.')[1]), CustomEncode.us_ascii);
            }

            return(ret);
        }
예제 #4
0
        /// <summary>MyJwt</summary>
        private static void MyJwt()
        {
            #region Variables

            string temp = "";
            bool   ret  = false;

            #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> payload = null;
            payload = new Dictionary <string, object>()
            {
                { "sub", "*****@*****.**" },
                { "exp", 1300819380 }
            };

            string payloadString = JsonConvert.SerializeObject(payload);
            #endregion

            #region Keys
            string jwk = "";

            #endregion

            #region JWS
            // RS256
            JWS_RS256_X509  jWS_RS256_X509  = null;
            JWS_RS256_Param jWS_RS256_Param = null;

            // ES256
#if NETCORE || NET47
            JWS_ES256_X509  jWS_ES256_X509  = null;
            JWS_ES256_Param jWS_ES256_Param = null;
#endif
            #endregion

            #region JWE
            JWE jwe = null;
            #endregion

            #endregion

            #region Jws
            if (os.Platform == PlatformID.Win32NT)
            {
                #region RSA(RS256)
                // 署名(X509)
                jWS_RS256_X509 = new JWS_RS256_X509(Program.PrivateRsaX509Path, Program.PfxPassword, x509KSF);
                token          = jWS_RS256_X509.Create(payloadString);
                MyDebug.InspectJwt("JWS_RS256_X509.Create", token);

                // 鍵の相互変換
                jwk = RsaPublicKeyConverter.ParamToJwk(((RSA)jWS_RS256_X509.DigitalSignX509.AsymmetricAlgorithm).ExportParameters(false));
                MyDebug.OutputDebugAndConsole("RSA JWK", jwk);

                // 検証(X509)
                jWS_RS256_X509 = new JWS_RS256_X509(Program.PublicRsaX509Path, "", x509KSF);
                MyDebug.OutputDebugAndConsole("JWS_RS256_X509.Verify", jWS_RS256_X509.Verify(token).ToString());

                // 検証(Param)
                jWS_RS256_Param = new JWS_RS256_Param(RsaPublicKeyConverter.JwkToParam(jwk));
                MyDebug.OutputDebugAndConsole("JWS_RS256_Param.Verify", jWS_RS256_Param.Verify(token).ToString());
                #endregion

                // DSA

#if NETCORE || NET47
                #region ECDsa(ES256)
                // 署名(X509)
                jWS_ES256_X509 = new JWS_ES256_X509(Program.PrivateECDsaX509Path, Program.PfxPassword);
                token          = jWS_ES256_X509.Create(payloadString);
                MyDebug.InspectJwt("JWS_ES256_X509.Create", token);

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

                MyDebug.OutputDebugAndConsole("ECDSA JWK", jwk);

                // 検証(X509)
                jWS_ES256_X509 = new JWS_ES256_X509(Program.PublicECDsaX509Path, "");
                MyDebug.OutputDebugAndConsole("JWS_ES256_X509.Verify", jWS_ES256_X509.Verify(token).ToString());

#if NET47 || NETCOREAPP3_0
                // 検証(Param)
                //// Core2.0-2.2 on WinでVerifyがエラーになる。
                //// DigitalSignECDsaOpenSslを試してみるが生成できない、
                //// Core on Win に OpenSSLベースのプロバイダは無いため)
                jWS_ES256_Param = new JWS_ES256_Param(EccPublicKeyConverter.JwkToParam(jwk), false);
                MyDebug.OutputDebugAndConsole("JWS_ES256_Param.Verify", jWS_ES256_Param.Verify(token).ToString());
#elif NETCOREAPP2_0
                // Core2.0-2.2 on Winで ECDsaCngは動作しない。
#endif
                // ★ xLibTest
                Program.VerifyResult("JwsAlgorithm.xLibTest", token, jWS_ES256_X509.DigitalSignECDsaX509.AsymmetricAlgorithm, JwsAlgorithm.ES256);

                #endregion
#endif
            }
            else //if (os.Platform == PlatformID.Unix)
            {
#if NETCORE
                #region RSA(RS256)
                // 署名(X509)
                jWS_RS256_X509 = new JWS_RS256_X509(Program.PrivateRsaX509Path, Program.PfxPassword, x509KSF);
                token          = jWS_RS256_X509.Create(payloadString);
                MyDebug.InspectJwt("JWS_RS256_X509.Create", token);

                // 鍵の相互変換
                jwk = RsaPublicKeyConverter.ParamToJwk(((RSA)jWS_RS256_X509.DigitalSignX509.AsymmetricAlgorithm).ExportParameters(false));
                MyDebug.OutputDebugAndConsole("RSA JWK", jwk);

                // 検証(X509)
                jWS_RS256_X509 = new JWS_RS256_X509(Program.PublicRsaX509Path, "", x509KSF);
                MyDebug.OutputDebugAndConsole("JWS_RS256_X509.Verify", jWS_RS256_X509.Verify(token).ToString());

                // 検証(Param)
                jWS_RS256_Param = new JWS_RS256_Param(RsaPublicKeyConverter.JwkToParam(jwk));
                MyDebug.OutputDebugAndConsole("JWS_RS256_Param.Verify", jWS_RS256_Param.Verify(token).ToString());
                #endregion

                // DSA

                #region ECDsa(ES256)
                // 署名(X509)
                jWS_ES256_X509 = new JWS_ES256_X509(Program.PrivateECDsaX509Path, Program.PfxPassword);
                token          = jWS_ES256_X509.Create(payloadString);
                MyDebug.InspectJwt("JWS_ES256_X509.Create", token);

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

                MyDebug.OutputDebugAndConsole("ECDSA JWK", jwk);

                // 検証(X509)
                jWS_ES256_X509 = new JWS_ES256_X509(Program.PublicECDsaX509Path, "");
                MyDebug.OutputDebugAndConsole("JWS_ES256_X509.Verify", jWS_ES256_X509.Verify(token).ToString());

                // 検証(Param)
                jWS_ES256_Param = new JWS_ES256_Param(EccPublicKeyConverter.JwkToParam(jwk), false);
                MyDebug.OutputDebugAndConsole("JWS_ES256_Param.Verify", jWS_ES256_X509.Verify(token).ToString());

                // ★ xLibTest
                Program.VerifyResult("JwsAlgorithm.xLibTest", token, jWS_ES256_X509.DigitalSignECDsaX509.AsymmetricAlgorithm, JwsAlgorithm.ES256);
                #endregion
#endif
            }
            #endregion

            #region Jwe

            #region RsaOaepAesGcm
            // 暗号化
            jwe   = new JWE_RsaOaepAesGcm_X509(Program.PublicRsaX509Path, "", x509KSF);
            token = jwe.Create(payloadString);

            // 復号化
            jwe = new JWE_RsaOaepAesGcm_X509(Program.PrivateRsaX509Path, Program.PfxPassword, x509KSF);
            ret = jwe.Decrypt(token, out temp);
            MyDebug.OutputDebugAndConsole("JWE_RsaOaepAesGcm_X509.Decrypt", ret.ToString() + " : " + temp);

            // ★ xLibTest
            Program.VerifyResult("JweAlgorithm.xLibTest", token,
                                 jwe.ASymmetricCryptography.AsymmetricAlgorithm, JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM);
            #endregion

            #region Rsa15A128CbcHS256
            // 暗号化
            jwe   = new JWE_Rsa15A128CbcHS256_X509(Program.PublicRsaX509Path, "", x509KSF);
            token = jwe.Create(payloadString);

            // 復号化
            jwe = new JWE_Rsa15A128CbcHS256_X509(Program.PrivateRsaX509Path, Program.PfxPassword, x509KSF);
            ret = jwe.Decrypt(token, out temp);
            MyDebug.OutputDebugAndConsole("JWE_Rsa15A128CbcHS256_X509.Decrypt", ret.ToString() + " : " + temp);

            // ★ xLibTest
            Program.VerifyResult("JweAlgorithm.xLibTest", token,
                                 jwe.ASymmetricCryptography.AsymmetricAlgorithm, JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256);

            #endregion

            #endregion
        }