예제 #1
0
        public void Data_of_various_length___roundtrips_correclty_as_string()
        {
            var sut   = new Base64UrlEncoder();
            var bytes = new byte[byte.MaxValue + 1];

            for (int i = 0; i < bytes.Length; ++i)
            {
                bytes[i] = (byte)(255 - i);
            }

            for (int i = 0; i < 256; ++i)
            {
                Span <byte> source  = bytes.AsSpan(0, i + 1);
                string      encoded = sut.Encode(source);
#if NETCOREAPP
                string encodedExpected = Convert.ToBase64String(source);
#else
                string encodedExpected = Convert.ToBase64String(source.ToArray());
#endif
                Assert.AreEqual(encodedExpected.ToBase64Url(), encoded);

                Span <byte> decoded = sut.Decode(encoded.AsSpan());

                CollectionAssert.AreEqual(source.ToArray(), decoded.ToArray());
            }
        }
예제 #2
0
        public async Task <string> CreateJwtAsync(JwtSecurityToken token)
        {
            var ecdsaCache = await _keyVaultECDsaKeyStore.FetchCacheAsync();

            string algorithm = ecdsaCache.SecurityKeyInfos.First().SigningAlgorithm;
            var    header    = Base64UrlEncoder.Encode(_serializer.Serialize(
                                                           new Dictionary <string, string>()
            {
                { JwtHeaderParameterNames.Alg, algorithm },
                { JwtHeaderParameterNames.Kid, ecdsaCache.CurrentKeyProperties.Version },
                { JwtHeaderParameterNames.Typ, "JWT" }
            }));
            var rawDataBytes = Encoding.UTF8.GetBytes(header + "." + token.EncodedPayload);

            byte[] hash;
            using (var hasher = CryptoHelper.GetHashAlgorithmForSigningAlgorithm(algorithm))
            {
                hash = hasher.ComputeHash(rawDataBytes);
            }
            var signResult = await ecdsaCache.CryptographyClient.SignAsync(
                new SignatureAlgorithm(algorithm), hash);

            var rawSignature = Base64UrlTextEncoder.Encode(signResult.Signature);

            return($"{header}.{token.EncodedPayload}.{rawSignature}");
        }
        public object CreateTokenJWT(TaiKhoanQuanLy request)
        {
            var result = new jwtResponse();

            var tokenDescription = new SecurityTokenDescriptor()
            {
                //info user and permission
                Subject = new ClaimsIdentity(new Claim[] {
                    new Claim("usrID", request.UsrID.ToString()),
                    new Claim("usrName", request.UserName),
                    new Claim("roleID", request.MaPhanQuyen.ToString())
                }),
                Expires            = DateTime.UtcNow.AddHours(1), //expires token
                SigningCredentials = new SigningCredentials(
                    new SymmetricSecurityKey(keySecretToken), SecurityAlgorithms.HmacSha256Signature)
            };

            var token = tokenHander.CreateToken(tokenDescription);

            result.jwtToken = tokenHander.WriteToken(token);
            result.isError  = false;

            var info = request.UsrID + "-" + request.UserName + "-" + request.MaPhanQuyen; //sercurity request refresh token

            result.jwtRefresh = Base64UrlEncoder.Encode(info);

            return(result);
        }
예제 #4
0
        public static JwksKey FromSigningCredentials(X509SigningCredentials signingCredentials)
        {
            X509Certificate2 certificate = signingCredentials.Certificate;

            // JWK cert data must be base64 (not base64url) encoded
            string certData = Convert.ToBase64String(certificate.Export(X509ContentType.Cert));

            // JWK thumbprints must be base64url encoded (no padding or special chars)
            string thumbprint = Base64UrlEncoder.Encode(certificate.GetCertHash());

            // JWK must have the modulus and exponent explicitly defined
            RSACng rsa = certificate.PublicKey.Key as RSACng;;

            if (rsa == null)
            {
                throw new Exception("Certificate is not an RSA certificate.");
            }

            RSAParameters keyParams   = rsa.ExportParameters(false);
            string        keyModulus  = Base64UrlEncoder.Encode(keyParams.Modulus);
            string        keyExponent = Base64UrlEncoder.Encode(keyParams.Exponent);

            return(new JwksKey
            {
                Kid = signingCredentials.Kid,
                Kty = "RSA",
                Nbf = new DateTimeOffset(certificate.NotBefore).ToUnixTimeSeconds(),
                Use = "sig",
                Alg = signingCredentials.Algorithm,
                X5C = new[] { certData },
                X5T = thumbprint,
                N = keyModulus,
                E = keyExponent
            });
        }
예제 #5
0
        public async Task <IApiResponse> HandleAsync(IApiRequest request)
        {
            var id = request.Body.Get <String>("id");

            if (String.IsNullOrEmpty(id))
            {
                return(Fail("id required"));
            }
            var user = await _userManager.FindAsync(new UserLoginInfo("ExternalId", id.ToUpperInvariant()));

            if (user == null)
            {
                return(Fail("User not found"));
            }
            var dp      = _dataProtectionProvider.Create("ExternalLogin");
            var data    = Encoding.UTF8.GetBytes($"{id.ToUpperInvariant().ToString()}\b{DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}");
            var protect = dp.Protect(data);
            var token   = Base64UrlEncoder.Encode(protect);
            var url     = $"{_context.Request.Uri.Authority}/account/loginext?token={token}";
            var res     = new ExpandoObject()
            {
                { "url", url }
            };

            return(Ok(res));
        }
        public Task OnGeneratingClaims(TokenGeneratingContext context)
        {
            if (context.CurrentToken.Equals(TokenTypes.IdToken) ||
                context.CurrentToken.Equals(TokenTypes.AccessToken))
            {
                var   userId              = context.User.FindFirstValue(_options.ClaimsIdentity.UserIdClaimType);
                var   applicationId       = context.Application.FindFirstValue(IdentityServiceClaimTypes.ObjectId);
                var   unHashedSubjectBits = Encoding.ASCII.GetBytes($"{userId}/{applicationId}");
                var   hashing             = CryptographyHelpers.CreateSHA256();
                var   subject             = Base64UrlEncoder.Encode(hashing.ComputeHash(unHashedSubjectBits));
                Claim existingClaim       = null;
                foreach (var claim in context.CurrentClaims)
                {
                    if (claim.Type.Equals(IdentityServiceClaimTypes.Subject, StringComparison.Ordinal))
                    {
                        existingClaim = claim;
                    }
                }

                if (existingClaim != null)
                {
                    context.CurrentClaims.Remove(existingClaim);
                }

                context.CurrentClaims.Add(new Claim(IdentityServiceClaimTypes.Subject, subject));
            }

            return(Task.CompletedTask);
        }
예제 #7
0
        public string GetJwt <T>(T claimsObject)
        {
            var certLocation = _certs.Last();
            var cert         = new X509Certificate2(_certData.GetValueOrDefault(certLocation) ?? new byte[] {}, _certPassword.GetValueOrDefault(certLocation));

            var rsa = cert.GetRSAPrivateKey();

            var key = new RsaSecurityKey(rsa)
            {
                KeyId = cert.Thumbprint
            };

            var signingCredentials = new SigningCredentials(key,
                                                            SecurityAlgorithms.RsaSha512, SecurityAlgorithms.RsaSha512);

            var header = new JwtHeader(signingCredentials).Base64UrlEncode();

            var body = Base64UrlEncoder.Encode(JsonSerializer.SerializeToUtf8Bytes(claimsObject));

            var firstParts = header + "." + body;

            var signature = JwtTokenUtilities.CreateEncodedSignature(firstParts, signingCredentials);

            return(firstParts + "." + signature);
        }
예제 #8
0
        static string GenerateJWT(RSA rsa)
        {
            //var securityKey = new Microsoft.IdentityModel.Tokens.X509SecurityKey(GetByThumbprint("YOUR-CERT-THUMBPRINT-HERE"));
            //var securityKey = new Microsoft.IdentityModel.Tokens.X509SecurityKey(new X509Certificate2(Convert.FromBase64String("MIIDBTCCAe2gAwIBAgIQbiJkXaenk61AKixVocnLRTANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE5MTAwNTAwMDAwMFoXDTI0MTAwNDAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ2H9Y6Z+3BXUCtlbmXr6H5owYy15XTl3vdpOZLUkk4OV9LMsB1phjNp+wgl28eAgrNNfu4BTVlHdR9x6NTrSiIapsYjzzEz4mOmRh1Bw5tJxit0VEGn00/ZENniTjgeEFYgDHYwjrfZQ6dERBFiw1OQb2IG5f3KLtx92lUXeIZ7ZvTaPkUpc4Qd6wQZmWgzPqWFocRsJATGyZzXiiXQUrc9cVqm1bws3P0lFBcqNtv+AKDYKT5IRYLsyCkueQC9R6LUCsZVD7bVIkeQuA3iehJKIEAlk/e3j5E4VaCRs642ajb/z9kByTl2xL2k0AeZGc8/Rcy7SQn0LBcJNZGp/SMCAwEAAaMhMB8wHQYDVR0OBBYEFOLhl3BDPLNVYDe38Dp9JbUmd4kKMA0GCSqGSIb3DQEBCwUAA4IBAQAN4XwyqYfVdMl0xEbBMa/OzSfIbuI4pQWWpl3isKRAyhXezAX1t/0532LsIcYkwubLifnjHHqo4x1jnVqkvkFjcPZ12kjs/q5d1L0LxlQST/Uqwm/9/AeTzRZXtUKNBWBOWy9gmw9DEH593sNYytGAEerbWhCR3agUxsnQSYTTwg4K9cSqLWzHX5Kcz0NLCGwLx015/Jc7HwPJnp7q5Bo0O0VfhomDiEctIFfzqE5x9T9ZTUSWUDn3J7DYzs2L1pDrOQaNs/YEkXsKDP1j4tOFyxic6OvjQ10Yugjo5jg1uWoxeU8pI0BxY6sj2GZt3Ynzev2bZqmj68y0I9Z+NTZo")));

            var securityKey = new Microsoft.IdentityModel.Tokens.RsaSecurityKey(rsa);

            var mod = rsa.ExportParameters(includePrivateParameters: false).Modulus;

            // The "key ID" used for RSA key in GPG/PGP is the last 8 hex digits (4 bytes) of the modulus of the key.
            securityKey.KeyId = Base64UrlEncode(mod, mod.Length - 4, 4);

            var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, "RS256");

            var header = new JwtHeader(credentials);

            var payload = new JwtPayload
            {
                { "aud", "https://management.core.windows.net/" },
                { "iss", "https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/" },
                { "exp", (Int32)(new DateTime(2019, 12, 9, 0, 0, 0, DateTimeKind.Utc).Subtract(new DateTime(1970, 1, 1))).TotalSeconds },
                { "iat", (Int32)(new DateTime(2019, 12, 7, 0, 0, 0, DateTimeKind.Utc).Subtract(new DateTime(1970, 1, 1))).TotalSeconds }
            };

            var token = new JwtSecurityToken(header, payload);

            var input     = string.Join(".", new[] { token.EncodedHeader, token.EncodedPayload });
            var signature = SignRS256(input, rsa);

            return(string.Join(".", new[] { input, Base64UrlEncoder.Encode(signature) }));
        }
        // Gmail :


        /// <summary>
        /// Sends an email.
        /// </summary>
        public void SendEmail(GmailService service, string _userId, string subject, string body, string from, string to, string fromAlias = "", string toAlias = "")
        {
            //_userId = "me";
            Console.WriteLine($"--- Starting SendEmail with userId {_userId}");
            var content =
                $"MIME - Version: 1.0\r\n" +
                $"Subject: {subject}\r\n" +
                $"From: {fromAlias}<{from}>\r\n" +
                $"To: {toAlias}<{to}>\r\n" +
                $"Content - Type: text / plain; charset = \"UTF-8\" \r\n" +
                $"\r\n" +
                $"{body}";

            Console.WriteLine($"--- content: {content}");
            content = Base64UrlEncoder.Encode(content.ToString());
            Console.WriteLine($"--- content (encoded): {content}");
            try
            {
                var message = new Message
                {
                    Raw = content
                };
                Console.WriteLine($"--- messageId: {message.Id}");

                //UsersResource.MessagesResource.SendRequest request = service.Users.Messages.Send(_userId)
                var result = service.Users.Messages.Send(message, _userId).Execute();

                Console.WriteLine($"--- result raw: {result.Raw}");
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: " + e.Message);
            }
        }
        public ActionResult Callback(
            string encodedRedirect,
            [FromQuery(Name = "code")] string code,
            [FromQuery(Name = "state")] string state,
            [FromQuery(Name = "session_state")] string sessionState,
            [FromQuery(Name = "error")] string error,
            [FromQuery(Name = "error_description")] string errorDescription)
        {
            Uri redirectUrl = new Uri(Base64UrlEncoder.Decode(encodedRedirect));

            if (!string.IsNullOrEmpty(error))
            {
                return(Redirect($"{redirectUrl.ToString()}?error={error}&error_description={errorDescription}"));
            }

            string compoundCode;
            string newState;

            try
            {
                JObject launchStateParameters = JObject.Parse(Base64UrlEncoder.Decode(state));
                JObject launchParameters      = JObject.Parse(Base64UrlEncoder.Decode(launchStateParameters["l"].ToString()));
                launchParameters.Add("code", code);
                newState     = launchStateParameters["s"].ToString();
                compoundCode = Base64UrlEncoder.Encode(launchParameters.ToString(Newtonsoft.Json.Formatting.None));
            }
            catch
            {
                _logger.LogError("Error parsing launch parameters.");
                return(BadRequest("Invalid launch context parameters"));
            }

            return(Redirect($"{redirectUrl.ToString()}?code={compoundCode}&state={newState}&session_state={sessionState}"));
        }
예제 #11
0
 private string GetComputedChallenge(string verifier)
 {
     using (var hash = CryptographyHelpers.CreateSHA256())
     {
         return(Base64UrlEncoder.Encode(hash.ComputeHash(Encoding.ASCII.GetBytes(verifier))));
     }
 }
        public async Task <ConfirmEmailQueryResult> Handle(ConfirmEmailQuery request,
                                                           CancellationToken cancellationToken)
        {
            var user = await _userManager.FindByIdAsync(request.UserId);

            if (user == null)
            {
                throw new DomainException($"User {request.UserId} is not found");
            }

            var decodedToken = Base64UrlEncoder.Decode(request.Token);
            var result       = await _userManager.ConfirmEmailAsync(user, decodedToken);

            var token = await _userManager.GeneratePasswordResetTokenAsync(user);

            var encodedToken = Base64UrlEncoder.Encode(token);

            return(new ConfirmEmailQueryResult
            {
                IsSuccess = result.Succeeded,
                Errors = result.Errors.Select(e => e.Description),
                ReturnUrl = request.ReturnUrl,
                ResetPasswordToken = encodedToken
            });
        }
예제 #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="options"></param>
        /// <param name="logger"></param>
        /// <exception cref="FileNotFoundException">证书文件不存在</exception>
        /// <exception cref="ArgumentException">Json无法解析</exception>
        public CredentialBiz(IOptions <AuthorizationOptions> options)
        {
            _options = options.Value;

            X509Certificate2?cert = CertificateUtil.GetBySubject(_options.CertificateSubject);

            if (cert == null)
            {
                throw new FileNotFoundException(_options.CertificateSubject);
            }

            X509SecurityKey securityKey = new X509SecurityKey(cert);

            _signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256Signature);

            RSA           publicKey  = (RSA)securityKey.PublicKey;
            RSAParameters parameters = publicKey.ExportParameters(false);

            IList <JsonWebKey> jsonWebKeys = new List <JsonWebKey> {
                new JsonWebKey {
                    Kty = "RSA",
                    Use = "sig",
                    Kid = securityKey.KeyId,
                    E   = Base64UrlEncoder.Encode(parameters.Exponent),
                    N   = Base64UrlEncoder.Encode(parameters.Modulus)
                }
            };

            string jsonWebKeySetString = SerializeUtil.ToJson(new { Keys = jsonWebKeys });

            _jsonWebKeySet = new JsonWebKeySet(jsonWebKeySetString);
        }
        /// <summary>
        /// Converts the <see cref="RsaJsonWebKey"/> into a JWK DTO
        /// </summary>
        /// <returns>A JWK DTO</returns>
        public override object ToJwkDto()
        {
            var modulus  = Base64UrlEncoder.Encode(m_parameters.Modulus);
            var exponent = Base64UrlEncoder.Encode(m_parameters.Exponent);

            if (ExpiresAt.HasValue)
            {
                return(new {
                    kid = Id,
                    kty = "RSA",
                    use = "sig",
                    n = modulus,
                    e = exponent,
                    exp = ExpiresAt.Value.ToUnixTimeSeconds()
                });
            }

            return(new {
                kid = Id,
                kty = "RSA",
                use = "sig",
                n = modulus,
                e = exponent,
            });
        }
        /// <summary>
        /// Produces a signature over the 'input'.
        /// </summary>
        /// <param name="input">String to be signed</param>
        /// <param name="signingCredentials">The <see cref="SigningCredentials"/> that contain crypto specs used to sign the token.</param>
        /// <returns>The bse64urlendcoded signature over the bytes obtained from UTF8Encoding.GetBytes( 'input' ).</returns>
        /// <exception cref="ArgumentNullException">'input' or 'signingCredentials' is null.</exception>
        public static string CreateEncodedSignature(string input, SigningCredentials signingCredentials)
        {
            if (input == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(input));
            }

            if (signingCredentials == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(signingCredentials));
            }

            var cryptoProviderFactory = signingCredentials.CryptoProviderFactory ?? signingCredentials.Key.CryptoProviderFactory;
            var signatureProvider     = cryptoProviderFactory.CreateForSigning(signingCredentials.Key, signingCredentials.Algorithm);

            if (signatureProvider == null)
            {
                throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(TokenLogMessages.IDX10636, (signingCredentials.Key == null ? "Null" : signingCredentials.Key.ToString()), (signingCredentials.Algorithm ?? "Null"))));
            }

            try
            {
                LogHelper.LogVerbose(LogMessages.IDX14200);
                return(Base64UrlEncoder.Encode(signatureProvider.Sign(Encoding.UTF8.GetBytes(input))));
            }
            finally
            {
                cryptoProviderFactory.ReleaseSignatureProvider(signatureProvider);
            }
        }
예제 #16
0
        /// <summary>
        ///     验证身份 验证签名的有效性,(TODO:待优化,需要重构)
        /// </summary>
        /// <param name="encodeJwt">转码之后的jwt信息</param>
        /// <param name="validatePayLoad"></param>
        /// <returns></returns>
        public static bool ValidateToken(string encodeJwt, Func <Dictionary <string, object>, bool> validatePayLoad)
        {
            var jwtOptions = AppSettingManager.Get <ESoftorJwtOption>("ESoftor:Jwt");

            var success = true;
            var jwtArr  = encodeJwt.Split('.');
            var header  = Base64UrlEncoder.Decode(jwtArr[0]).FromJsonString <Dictionary <string, object> >();
            var payLoad = Base64UrlEncoder.Decode(jwtArr[1]).FromJsonString <Dictionary <string, object> >();

            var hs256 = new HMACSHA256(Encoding.ASCII.GetBytes(jwtOptions.Secret));

            //首先验证签名是否正确(必须的)
            success = success && string.Equals(jwtArr[2], Base64UrlEncoder.Encode(hs256.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(jwtArr[0], ".", jwtArr[1])))));
            if (!success)
            {
                return(success);//签名不正确直接返回
            }
            //其次验证是否在有效期内(也应该必须)
            var now = Convert.ToInt64(DateTime.UtcNow.ToJsGetTime());

            success = success && (now >= long.Parse(payLoad["nbf"].ToString()) && now < long.Parse(payLoad["exp"].ToString()));

            //再其次 进行自定义的验证
            success = success && validatePayLoad(payLoad);

            return(success);
        }
        public static async Task <string> CreateDeviceAuthChallengeResponseAsync(IDictionary <string, string> challengeData)
        {
            string      authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";
            Certificate certificate        = null;

            try
            {
                certificate = await FindCertificate(challengeData).ConfigureAwait(false);
            }
            catch (AdalException ex)
            {
                if (ex.ErrorCode == AdalError.DeviceCertificateNotFound)
                {
                    return(await Task.FromResult(string.Format(CultureInfo.InvariantCulture, @"PKeyAuth Context=""{0}"",Version=""{1}""", challengeData["Context"], challengeData["Version"])).ConfigureAwait(false));
                }
            }
            DeviceAuthJWTResponse response = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                       challengeData["nonce"], Convert.ToBase64String(certificate.GetCertificateBlob().ToArray()));
            IBuffer input = CryptographicBuffer.ConvertStringToBinary(response.GetResponseToSign(),
                                                                      BinaryStringEncoding.Utf8);
            CryptographicKey keyPair = await
                                       PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256,
                                                                                            CryptographicPadding.RsaPkcs1V15).AsTask().ConfigureAwait(false);

            IBuffer signed = await CryptographicEngine.SignAsync(keyPair, input).AsTask().ConfigureAwait(false);

            string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", response.GetResponseToSign(),
                                             Base64UrlEncoder.Encode(signed.ToArray()));
            string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt);

            return(string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]));
        }
예제 #18
0
        /// <summary>
        /// Produces a signature over the 'input'.
        /// </summary>
        /// <param name="input">String to be signed</param>
        /// <param name="signingCredentials">The <see cref="SigningCredentials"/> that contain crypto specs used to sign the token.</param>
        /// <returns>The bse64urlendcoded signature over the bytes obtained from UTF8Encoding.GetBytes( 'input' ).</returns>
        /// <exception cref="ArgumentNullException">'input' or 'signingCredentials' is null.</exception>
        internal static string CreateEncodedSignature(string input, SigningCredentials signingCredentials)
        {
            if (input == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(input));
            }

            if (signingCredentials == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(signingCredentials));
            }

            var cryptoProviderFactory = signingCredentials.CryptoProviderFactory ?? signingCredentials.Key.CryptoProviderFactory;
            var signatureProvider     = cryptoProviderFactory.CreateForSigning(signingCredentials.Key, signingCredentials.Algorithm);

            if (signatureProvider == null)
            {
                throw LogHelper.LogException <InvalidOperationException>("LogMessages.IDX10636", (signingCredentials.Key == null ? "Null" : signingCredentials.Key.ToString()), (signingCredentials.Algorithm ?? "Null"));
            }

            try
            {
                IdentityModelEventSource.Logger.WriteVerbose("LogMessages.IDX10645");
                return(Base64UrlEncoder.Encode(signatureProvider.Sign(Encoding.UTF8.GetBytes(input))));
            }
            finally
            {
                cryptoProviderFactory.ReleaseSignatureProvider(signatureProvider);
            }
        }
예제 #19
0
        public static string GenerateLoginToken(int playerID, DateTime tokenTTL)
        {
            //Setup Header
            TokenHeader header    = new TokenHeader();
            string      jwtHeader = JsonSerializer.Serialize(header);

            byte[] headerBytes   = Encoding.UTF8.GetBytes(jwtHeader);
            string encodedHeader = Base64UrlEncoder.Encode(headerBytes);

            //Setup data body
            TokenBody body    = new TokenBody(playerID, tokenTTL);
            string    jwtBody = JsonSerializer.Serialize(body);

            byte[] bodyBytes   = Encoding.UTF8.GetBytes(jwtBody);
            string encodedBody = Base64UrlEncoder.Encode(bodyBytes);

            string jwtToken = $"{encodedHeader}.{encodedBody}";

            string jwtSignature     = GetTokenSignature(jwtToken);
            string encodedSignature = Base64UrlEncoder.Encode(jwtSignature);

            string signedJWTToken = $"{jwtToken}.{encodedSignature}";

            return(signedJWTToken);
        }
        public void ComputeJwkThumbprintSpec()
        {
            // https://datatracker.ietf.org/doc/html/rfc7638#section-3.1
            var context = TestUtilities.WriteHeader($"{this}.ComputeJwkThumbprintSpec", "", true);

            var jwk = new JsonWebKey()
            {
                Kty = JsonWebAlgorithmsKeyTypes.RSA,
                E   = "AQAB",
                N   = "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"
            };

            var jwkThumbprint = jwk.ComputeJwkThumbprint();
            var base64UrlEncodedJwkThumbprint = Base64UrlEncoder.Encode(jwkThumbprint);

            var expectedJwkThumbprint = new byte[]
            {
                55, 54, 203, 177, 120, 124, 184, 48, 156, 119, 238, 140, 55, 5, 197,
                225, 111, 251, 158, 133, 151, 21, 144, 31, 30, 76, 89, 177, 17, 130,
                245, 123
            };
            var expectedBase64UrlEncodedThumbprint = "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs";

            IdentityComparer.AreBytesEqual(jwkThumbprint, expectedJwkThumbprint, context);
            IdentityComparer.AreStringsEqual(base64UrlEncodedJwkThumbprint, expectedBase64UrlEncodedThumbprint, context);
            TestUtilities.AssertFailIfErrors(context);
        }
예제 #21
0
        private async Task <string> GetAuthTokenAsync()
        {
            var request = new HttpRequestMessage(HttpMethod.Post, UrlConfig.Authorize());

            var content = new List <KeyValuePair <string, string> >
            {
                new KeyValuePair <string, string>("grant_type", "client_credentials")
            };

            request.Content = new FormUrlEncodedContent(content);

            var authHeader = Base64UrlEncoder.Encode($"{_appSettings.ClientId}:{_appSettings.ClientSecret}");

            request.Headers.Add("Authorization", $"Basic {authHeader}");

            var client   = _clientFactory.CreateClient();
            var response = await client.SendAsync(request);

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception("Unable to Authenticate with SpotifyId servers.");
            }

            var json = await response.Content.ReadAsStringAsync();

            var token = JsonConvert.DeserializeObject <AuthResponse>(json);

            return($"{token.TokenType} {token.AccessToken}");
        }
예제 #22
0
        /// <summary>
        /// Converts the <see cref="RsaJsonWebKey"/> into a JWK DTO
        /// </summary>
        /// <returns>A JWK DTO</returns>
        public override object ToJwkDto()
        {
            var modulus  = Base64UrlEncoder.Encode(m_parameters.Modulus);
            var exponent = Base64UrlEncoder.Encode(m_parameters.Exponent);

            if (ExpiresAt.HasValue)
            {
                return(new {
                    kid = Id.ToString(),
                    kty = "RSA",
                    use = "sig",
                    n = modulus,
                    e = exponent,
                    exp = (long)ExpiresAt.Value.TimeSinceUnixEpoch().TotalSeconds
                });
            }

            return(new {
                kid = Id.ToString(),
                kty = "RSA",
                use = "sig",
                n = modulus,
                e = exponent,
            });
        }
        public static async Task <string> CreateDeviceAuthChallengeResponse(IDictionary <string, string> challengeData)
        {
            string authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";

            X509Certificate2      certificate = FindCertificate(challengeData);
            DeviceAuthJWTResponse response    = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                          challengeData["nonce"], Convert.ToBase64String(certificate.GetRawCertData()));
            CngKey key = CryptographyHelper.GetCngPrivateKey(certificate);

            byte[] sig = null;
            using (RSACng rsa = new RSACng(key))
            {
                rsa.SignatureHashAlgorithm = CngAlgorithm.Sha256;
                sig = rsa.SignData(response.GetResponseToSign().ToByteArray());
            }

            string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", response.GetResponseToSign(),
                                             Base64UrlEncoder.Encode(sig));
            string        authToken  = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt);
            Task <string> resultTask =
                Task.Factory.StartNew(
                    () =>
            {
                return(string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken,
                                     challengeData["Context"],
                                     challengeData["Version"]));
            });

            return(await resultTask.ConfigureAwait(false));
        }
        public async Task <string> BuildSerializedIdTokenAsync(string issuer, string audience, int duration, string userEmail)
        {
            // Parameters that are transmited in the ID Token assertion are communicated as claims
            var claims = new List <System.Security.Claims.Claim>
            {
                new System.Security.Claims.Claim("email", userEmail, System.Security.Claims.ClaimValueTypes.String, issuer)
            };
            var header  = new JwtHeader(_vaultCryptoValues.Value.SigningCredentials);
            var payload = new JwtPayload(
                issuer,
                audience,
                claims,
                DateTime.Now,
                DateTime.Now.AddMinutes(duration));

            // Use the intended JWT Token's Header and Payload value as the data for the token's Signature
            var unsignedTokenText = $"{header.Base64UrlEncode()}.{payload.Base64UrlEncode()}";
            var byteData          = Encoding.UTF8.GetBytes(unsignedTokenText);

            // Use KV Cryptography Client to compute the signature
            var cryptographyClient = _vaultCryptoValues.Value.CryptographyClient;
            // SignData will create the digest and encode it (whereas Sign requires that the digest is computed here and to be sent in.)
            var signatureResult = await cryptographyClient
                                  .SignDataAsync(_vaultCryptoValues.Value.SigningCredentials.Algorithm, byteData)
                                  .ConfigureAwait(false);

            var encodedSignature = Base64UrlEncoder.Encode(signatureResult.Signature);

            // Assemble the header, payload, and encoded signatures
            var result = $"{unsignedTokenText}.{encodedSignature}";

            return(result);
        }
예제 #25
0
        /// <summary>
        /// Initializes a new instance of <see cref="JwtHeader"/>.
        /// With the Header Parameters:
        /// <para>{ { typ, JWT }, { alg, SigningCredentials.Algorithm } }</para>
        /// </summary>
        /// <param name="signingCredentials"><see cref="SigningCredentials"/> used when creating a JWS Compact JSON.</param>
        /// <param name="outboundAlgorithmMap">provides a mapping for the 'alg' value so that values are within the JWT namespace.</param>
        public JwtHeader(SigningCredentials signingCredentials, IDictionary <string, string> outboundAlgorithmMap)
            : base(StringComparer.Ordinal)
        {
            if (signingCredentials == null)
            {
                this[JwtHeaderParameterNames.Alg] = SecurityAlgorithms.None;
            }
            else
            {
                if (outboundAlgorithmMap != null && outboundAlgorithmMap.TryGetValue(signingCredentials.Algorithm, out string outboundAlg))
                {
                    Alg = outboundAlg;
                }
                else
                {
                    Alg = signingCredentials.Algorithm;
                }

                if (!string.IsNullOrEmpty(signingCredentials.Key.KeyId))
                {
                    Kid = signingCredentials.Key.KeyId;
                }

                if (signingCredentials is X509SigningCredentials x509SigningCredentials)
                {
                    this[JwtHeaderParameterNames.X5t] = Base64UrlEncoder.Encode(x509SigningCredentials.Certificate.GetCertHash());
                }
            }

            Typ = JwtConstants.HeaderType;
            SigningCredentials = signingCredentials;
        }
예제 #26
0
        private static JsonWebKeySet GetJsonWebKeySet(RsaKeyParameters keyParameters)
        {
            var e    = Base64UrlEncoder.Encode(keyParameters.Exponent.ToByteArrayUnsigned());
            var n    = Base64UrlEncoder.Encode(keyParameters.Modulus.ToByteArrayUnsigned());
            var dict = new Dictionary <string, string>
            {
                { "e", e },
                { "kty", "RSA" },
                { "n", n }
            };
            var hash       = SHA256.Create();
            var hashBytes  = hash.ComputeHash(System.Text.Encoding.ASCII.GetBytes(JsonSerializer.SerializeToString(dict)));
            var jsonWebKey = new JsonWebKey
            {
                Kid = Base64UrlEncoder.Encode(hashBytes),
                Kty = "RSA",
                E   = e,
                N   = n
            };
            var jsonWebKeySet = new JsonWebKeySet();

            jsonWebKeySet.Keys.Add(jsonWebKey);

            return(jsonWebKeySet);
        }
예제 #27
0
        /// <summary>
        /// 校验
        /// </summary>
        /// <param name="encodeJwt">加密后的Jwt令牌</param>
        /// <param name="options">Jwt选项配置</param>
        /// <param name="validatePayload">校验负载</param>
        public bool Validate(string encodeJwt, JwtOptions options, Func <IDictionary <string, string>, JwtOptions, bool> validatePayload)
        {
            if (string.IsNullOrWhiteSpace(options.Secret))
            {
                throw new ArgumentNullException(nameof(options.Secret),
                                                $@"{nameof(options.Secret)}为Null或空字符串。请在""appsettings.json""配置""{nameof(JwtOptions)}""节点及其子节点""{nameof(JwtOptions.Secret)}""");
            }
            var jwtArray = encodeJwt.Split('.');

            if (jwtArray.Length < 3)
            {
                return(false);
            }
            var header  = JsonHelper.ToObject <Dictionary <string, string> >(Base64UrlEncoder.Decode(jwtArray[0]));
            var payload = JsonHelper.ToObject <Dictionary <string, string> >(Base64UrlEncoder.Decode(jwtArray[1]));

            // 首先验证签名是否正确
            var hs256 = new HMACSHA256(Encoding.UTF8.GetBytes(options.Secret));
            var sign  = Base64UrlEncoder.Encode(
                hs256.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(jwtArray[0], ".", jwtArray[1]))));

            // 签名不正确直接返回
            if (!string.Equals(jwtArray[2], sign))
            {
                return(false);
            }
            // 其次验证是否在有效期内
            //var now = ToUnixEpochDate(DateTime.UtcNow);
            //if (!(now >= long.Parse(payload["nbf"].ToString()) && now < long.Parse(payload["exp"].ToString())))
            //    return false;
            // 进行自定义验证
            return(validatePayload(payload, options));
        }
예제 #28
0
파일: JWTHelper.cs 프로젝트: HkSuen/House
        public string CreateToken(Dictionary <string, object> payLoad = null, int expiresMinute = 2, Dictionary <string, object> header = null)
        {
            if (header == null)
            {
                header = new Dictionary <string, object>()
                {
                    { "alg", "HS256" },
                    { "typ", "JWT" }
                };
            }
            if (payLoad == null)
            {
                payLoad = new Dictionary <string, object>();
            }
            var now = DateTime.UtcNow;

            payLoad["nbf"] = ToUnixEpochDate(now);                                          //可用时间起始
            payLoad["exp"] = ToUnixEpochDate(now.Add(TimeSpan.FromMinutes(expiresMinute))); //可用时间结束
            var encodedHeader    = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(header));
            var encodedPayload   = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(payLoad));
            var hs256            = new HMACSHA256(Encoding.ASCII.GetBytes(securityKey));
            var encodedSignature = Base64UrlEncoder.Encode(hs256.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(encodedHeader, ".", encodedPayload))));
            var encodedJwt       = string.Concat(encodedHeader, ".", encodedPayload, ".", encodedSignature);

            return(encodedJwt);
        }
        // Validate the claim value against the actual data
        private void ValidateClaim(Dictionary <string, string> claims, string claimName, byte[] actualData)
        {
            // Get required claim data
            string claimData;
            bool   hasClaim = claims.TryGetValue(claimName, out claimData);

            if (!hasClaim)
            {
                throw new AlwaysEncryptedAttestationException(string.Format(Strings.MissingClaimInAttestationToken, claimName));
            }

            // Get the Base64Url of the actual data and compare it with claim
            string encodedActualData = string.Empty;

            try
            {
                encodedActualData = Base64UrlEncoder.Encode(actualData);
            }
            catch (Exception)
            {
                throw new AlwaysEncryptedAttestationException(Strings.InvalidArgumentToBase64UrlDecoder);
            }

            bool hasValidClaim = string.Equals(encodedActualData, claimData, StringComparison.Ordinal);

            if (!hasValidClaim)
            {
                throw new AlwaysEncryptedAttestationException(string.Format(Strings.InvalidClaimInAttestationToken, claimName, claimData));
            }
        }
        private static string CreateSign(X509Certificate2 cert, string encodedHeaderAndPayload)
        {
            var rsaP   = cert.GetRSAPrivateKey();
            var signed = rsaP.SignData(Encoding.UTF8.GetBytes(encodedHeaderAndPayload), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

            return(Base64UrlEncoder.Encode(signed));
        }