/// <summary>
 /// code_challenge_method=S256
 /// BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))</summary>
 /// <param name="code_verifier">string</param>
 /// <returns>code_challenge</returns>
 public static string PKCE_S256_CodeChallengeMethod(string code_verifier)
 {
     return(CustomEncode.ToBase64UrlString(
                GetHash.GetHashBytes(
                    CustomEncode.StringToByte(code_verifier, CustomEncode.us_ascii),
                    EnumHashAlgorithm.SHA256_M)));
 }
        /// <summary>CreateJwkFromDictionary</summary>
        /// <param name="dic">Dictionary</param>
        /// <param name="settings">JsonSerializerSettings</param>
        /// <returns>JwkString</returns>
        internal static string CreateJwkFromDictionary(
            Dictionary <string, string> dic,
            JsonSerializerSettings settings = null)
        {
            // JSON Web Key (JWK) Thumbprint
            // https://openid-foundation-japan.github.io/rfc7638.ja.html
            // kid : https://openid-foundation-japan.github.io/rfc7638.ja.html#Example
            //       https://openid-foundation-japan.github.io/rfc7638.ja.html#MembersUsed
            //       kidには、JWK の JWK Thumbprint 値などが用いられるらしい。
            //       ★ EC 公開鍵の必須メンバを辞書順に並べると、crv, kty, x, y となる。
            dic[JwtConst.kid] = CustomEncode.ToBase64UrlString(
                GetHash.GetHashBytes(
                    CustomEncode.StringToByte(
                        JsonConvert.SerializeObject(new
            {
                crv = dic[JwtConst.crv],
                kty = dic[JwtConst.kty],
                x   = dic[JwtConst.x],
                y   = dic[JwtConst.y]
            }),
                        CustomEncode.UTF_8),
                    EnumHashAlgorithm.SHA256_M));

            //dic["ext"] = "false"; // 定義をRFC上に発見できない。

            if (settings == null)
            {
                return(JsonConvert.SerializeObject(dic));
            }
            else
            {
                return(JsonConvert.SerializeObject(dic, settings));
            }
        }
예제 #3
0
 /// <summary>
 /// SHA256でat_hash, c_hashを作成。
 /// (現時点でRS256固定になっているので)
 /// </summary>
 /// <returns>hash</returns>
 public static string CreateHash(string input)
 {
     // ID Token の JOSE Header にある alg Header Parameterのアルゴリズムで使用されるハッシュアルゴリズムを用い、
     // input(access_token や code) のASCII オクテット列からハッシュ値を求め、左半分を base64url エンコードした値。
     return(CustomEncode.ToBase64UrlString(
                PubCmnFunction.ShortenByteArray(
                    GetHash.GetHashBytes(
                        CustomEncode.StringToByte(input, CustomEncode.us_ascii),
                        EnumHashAlgorithm.SHA256Managed), (256 / 2))));
 }
예제 #4
0
파일: Form1.cs 프로젝트: ukayare/OpenTouryo
 /// <summary>ハッシュ</summary>
 private void btnGetHash_Click(object sender, EventArgs e)
 {
     if (this.rbnHSString.Checked)
     {
         txtHSCode.Text = GetHash.GetHashString(
             txtHSString.Text, (EnumHashAlgorithm)cbxHSPV.SelectedValue);
     }
     else
     {
         txtHSCode.Text = CustomEncode.ToHexString(GetHash.GetHashBytes(
                                                       CustomEncode.StringToByte(txtHSString.Text, CustomEncode.UTF_8), (EnumHashAlgorithm)cbxHSPV.SelectedValue));
     }
 }
예제 #5
0
        /// <summary>
        /// at_hash, c_hash, s_hashを作成
        /// (SHA256→HS256,RS256,ES256対応可能)
        /// </summary>
        /// <param name="input">string</param>
        /// <returns>hash</returns>
        public static string CreateHash(string input)
        {
            // ID Token の JOSE Header にある
            // alg Header Parameterのアルゴリズムで使用されるハッシュアルゴリズムを用い、
            // input(access_token や code) のASCII オクテット列からハッシュ値を求め、
            byte[] bytes = GetHash.GetHashBytes(
                CustomEncode.StringToByte(input, CustomEncode.us_ascii),
                EnumHashAlgorithm.SHA256_M);

            // 左半分を base64url エンコードした値。
            return(CustomEncode.ToBase64UrlString(
                       ArrayOperator.ShortenByteArray(bytes, (bytes.Length / 2))));
        }
        // <参考>
        // JSON Web Key (JWK)
        // https://openid-foundation-japan.github.io/rfc7517.ja.html
        //   を、"kty":"RSA"で検索するとイイ。
        //
        // A.1.  Example Public Keys
        // https://openid-foundation-japan.github.io/rfc7517.ja.html#PublicExample
        // A.2.  Example Private Keys
        // https://openid-foundation-japan.github.io/rfc7517.ja.html#PrivateExample
        // C.1.  Plaintext RSA Private Key
        // https://openid-foundation-japan.github.io/rfc7517.ja.html#example-privkey-plaintext

        // ECCurve support of EccKey.
        // https://github.com/dvsekhvalnov/jose-jwt/issues/105
        // RSAParameters ⇔ Jwk
        // https://github.com/psteniusubi/jose-jwt/blob/master/jose-jwt/jwk/JwkRsa.cs
        // <Param to jwk>                             // <Jwk to param>
        //header.Set("kty", "RSA");                   //RSAParameters parameters = new RSAParameters();
        //header.Set("n", parameters.Modulus);        //parameters.Modulus = header.GetBytes("n");
        //header.Set("e", parameters.Exponent);       //parameters.Exponent = header.GetBytes("e");
        //
        // ココから下は秘密鍵の領域                   // ココから下は秘密鍵の領域
        //if (includePrivateParameters)               //if (header.ContainsKey("d"))
        //{                                           //{
        //    header.Set("d", parameters.D);          //    parameters.D = header.GetBytes("d");
        //    header.Set("p", parameters.P);          //    parameters.P = header.GetBytes("p");
        //    header.Set("q", parameters.Q);          //    parameters.Q = header.GetBytes("q");
        //    header.Set("dp", parameters.DP);        //    parameters.DP = header.GetBytes("dp");
        //    header.Set("dq", parameters.DQ);        //    parameters.DQ = header.GetBytes("dq");
        //    header.Set("qi", parameters.InverseQ);  //    parameters.InverseQ = header.GetBytes("qi");
        //}                                           //}
        //                                            // ↓↓↓
        //                                            //RSA rsa = RSA.Create();
        //                                            //rsa.ImportParameters(parameters);
        //                                            //return rsa;

        #region ParamToJwk
        /// <summary>ParamToJwk</summary>
        /// <param name="param">RSAParameters</param>
        /// <param name="settings">JsonSerializerSettings</param>
        /// <returns>Jwk公開鍵</returns>
        public string ParamToJwk(
            RSAParameters param,
            JsonSerializerSettings settings = null)
        {
            Dictionary <string, string> dic = new Dictionary <string, string>();

            dic[JwtConst.kty] = JwtConst.RSA; // 必須
            dic[JwtConst.alg] = this.JwtConstRSnnn;

            // Public
            dic[JwtConst.n] = CustomEncode.ToBase64UrlString(param.Modulus);
            dic[JwtConst.e] = CustomEncode.ToBase64UrlString(param.Exponent); //"AQAB";

            // JSON Web Key (JWK) Thumbprint
            // https://openid-foundation-japan.github.io/rfc7638.ja.html
            // kid : https://openid-foundation-japan.github.io/rfc7638.ja.html#Example
            //       https://openid-foundation-japan.github.io/rfc7638.ja.html#MembersUsed
            //       kidには、JWK の JWK Thumbprint 値などが用いられるらしい。
            //       ★ RSA 公開鍵の必須メンバを辞書順に並べると、e, kty, n となる。

            dic[JwtConst.kid] = CustomEncode.ToBase64UrlString(
                GetHash.GetHashBytes(
                    CustomEncode.StringToByte(
                        JsonConvert.SerializeObject(new
            {
                e   = dic[JwtConst.e],
                kty = dic[JwtConst.kty],
                n   = dic[JwtConst.n]
            }),
                        CustomEncode.UTF_8),
                    this.HashAlgorithm));

            //dic["ext"] = "false"; // 定義をRFC上に発見できない。

            if (settings == null)
            {
                return(JsonConvert.SerializeObject(dic));
            }
            else
            {
                return(JsonConvert.SerializeObject(dic, settings));
            }
        }
예제 #7
0
        /// <summary>ValidateSignature</summary>

        /// <param name="clientData">string</param>
        /// <param name="authenticatorData">string</param>
        /// <param name="signature">string</param>
        /// <returns>
        /// true  : valid
        /// false : invalid
        /// </returns>
        public bool ValidateSignature(
            string clientData, string authenticatorData, string signature)
        {
            bool ret = false;

            byte[] clientDataBytes        = CustomEncode.FromBase64UrlString(clientData);
            byte[] authenticatorDataBytes = CustomEncode.FromBase64UrlString(authenticatorData);
            byte[] signatureBytes         = CustomEncode.FromBase64UrlString(signature);

            // Challengeの一致を確認する。
            JObject clientJson = JObject.Parse(//Encoding.ASCII.GetString(clientDataBytes));
                Encoding.ASCII.GetString(clientDataBytes).Replace("\0", "").Trim());

            byte[] hashBytes = null;
            byte[] data      = null;
            hashBytes = GetHash.GetHashBytes(clientDataBytes, EnumHashAlgorithm.SHA256Managed, 0);
            data      = authenticatorDataBytes.Concat(hashBytes).ToArray();

            if ((string)clientJson["challenge"] == this.Challenge)
            {
                // Challengeの一致

                // Load public key
                RSACryptoServiceProvider rsaCryptoServiceProvider =
                    RS256_KeyConverter.JwkToProvider(this.PublicKey);

                // VerifyData
                ret = rsaCryptoServiceProvider.VerifyData(
                    data, signatureBytes,
                    HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

                return(ret);
            }
            else
            {
                // Challengeの不一致
                return(false);
            }
        }