public static string valueOf(JWTAlgorithm jWTAlgorithm, Error error)
        {
            switch (jWTAlgorithm)
            {
            case JWTAlgorithm.HS256:
                return("HS256");

            case JWTAlgorithm.HS512:
                return("HS512");

            case JWTAlgorithm.RS256:
                return("RS256");

            case JWTAlgorithm.RS512:
                return("RS512");

            case JWTAlgorithm.ES256:
                return("ES256");

            case JWTAlgorithm.ES384:
                return("ES384");

            case JWTAlgorithm.ES512:
                return("ES512");

            default:
                error.setError("JA001", "Unrecognized algorithm");
                return("Unrecognized algorithm");
            }
        }
예제 #2
0
        /// <summary>
        /// Hash a token signature
        /// </summary>
        /// <param name="algorithm"><see cref="JWTAlgorithm"/> to encrypt</param>
        /// <param name="keyBytes">Key</param>
        /// <param name="payloadBytes">Payload</param>
        /// <returns>Hashed Signature</returns>
        public static byte[] HashSignature(JWTAlgorithm algorithm, byte[] keyBytes, byte[] payloadBytes)
        {
            byte[] hashedBytes = null;
            switch (algorithm)
            {
            case JWTAlgorithm.HS256:
                HMACSHA256 encHMAC256 = new HMACSHA256(keyBytes);
                hashedBytes = encHMAC256.ComputeHash(payloadBytes);
                break;

            case JWTAlgorithm.HS384:
                HMACSHA384 encHMAC384 = new HMACSHA384(keyBytes);
                hashedBytes = encHMAC384.ComputeHash(payloadBytes);
                break;

            case JWTAlgorithm.HS512:
                HMACSHA512 encHMAC512 = new HMACSHA512(keyBytes);
                hashedBytes = encHMAC512.ComputeHash(payloadBytes);
                break;

            default:
                // temporary impementation of a default encryption
                goto case JWTAlgorithm.HS256;
            }
            return(hashedBytes);
        }
        internal static SigningCredentials getSigningCredentials(JWTAlgorithm jWTAlgorithm, SecurityKey key, Error error)
        {
            switch (jWTAlgorithm)
            {
            case JWTAlgorithm.HS256:
                return(new SigningCredentials(key, SecurityAlgorithms.HmacSha256));

            case JWTAlgorithm.HS512:
                return(new SigningCredentials(key, SecurityAlgorithms.HmacSha512));

            case JWTAlgorithm.RS256:
                return(new SigningCredentials(key, SecurityAlgorithms.RsaSha256));

            case JWTAlgorithm.RS512:
                return(new SigningCredentials(key, SecurityAlgorithms.RsaSha512));

            case JWTAlgorithm.ES256:
                return(new SigningCredentials(key, SecurityAlgorithms.EcdsaSha256));

            case JWTAlgorithm.ES384:
                return(new SigningCredentials(key, SecurityAlgorithms.EcdsaSha384));

            case JWTAlgorithm.ES512:
                return(new SigningCredentials(key, SecurityAlgorithms.EcdsaSha512));

            default:
                error.setError("JA003", "Unknown algorithm");
                return(null);
            }
        }
        public static bool isPrivate(JWTAlgorithm jWTAlgorithm)
        {
            switch (jWTAlgorithm)
            {
            case JWTAlgorithm.RS256:
            case JWTAlgorithm.RS512:
            case JWTAlgorithm.ES256:
            case JWTAlgorithm.ES384:
            case JWTAlgorithm.ES512:

                return(true);

            default:
                return(false);
            }
        }
        private static JWTHeader GetHeader(VssSigningCredentials credentials, bool allowExpired)
        {
            //note credentials are allowed to be null here, see ValidateSigningCredentials
            JWTHeader header = new JWTHeader();

            JWTAlgorithm alg = JsonWebTokenUtilities.ValidateSigningCredentials(credentials, allowExpired);

            header.Algorithm = alg;

            if (alg != JWTAlgorithm.None)
            {
                // Some signing credentials may need to set headers for the JWT
                var jwtHeaderProvider = credentials as IJsonWebTokenHeaderProvider;
                if (jwtHeaderProvider != null)
                {
                    jwtHeaderProvider.SetHeaders(header);
                }
            }

            return(header);
        }
        //if we alread have the alg, we assume that the creds have been validated already,
        //to save the expense of validating twice in the create function...
        private static byte[] GetSignature(JWTHeader header, JWTPayload payload, JWTAlgorithm alg, VssSigningCredentials signingCredentials)
        {
            if (alg == JWTAlgorithm.None)
            {
                return(null);
            }

            ArgumentUtility.CheckForNull(header, nameof(header));
            ArgumentUtility.CheckForNull(payload, nameof(payload));

            string encoding = string.Format("{0}.{1}", header.JsonEncode(), payload.JsonEncode());

            byte[] bytes = Encoding.UTF8.GetBytes(encoding);

            switch (alg)
            {
            case JWTAlgorithm.HS256:
            case JWTAlgorithm.RS256:
                return(signingCredentials.SignData(bytes));

            default:
                throw new InvalidOperationException();
            }
        }
        private static byte[] GetSignature(JWTHeader header, JWTPayload payload, VssSigningCredentials credentials, bool allowExpired)
        {
            JWTAlgorithm alg = JsonWebTokenUtilities.ValidateSigningCredentials(credentials, allowExpired);

            return(GetSignature(header, payload, alg, credentials));
        }
예제 #8
0
        /// <summary>
        /// Verifies asynchronously if this token is valid using the token signature
        /// </summary>
        /// <returns><see cref="bool"/></returns>
        public static Task <bool> VerifyAsync(string token, string key)
        {
            var task = Task.Run(() =>
            {
                DateTime startTime = DateTime.Now;
                if (string.IsNullOrEmpty(token))
                {
                    throw new ArgumentNullException("Token");
                }

                if (string.IsNullOrEmpty(key))
                {
                    throw new ArgumentNullException("Key");
                }

                string[] parts = token.Split('.');
                if (parts.Count() < 3)
                {
                    throw new ArgumentException("Token not correcty constructed.");
                }

                string headerJson    = parts[0].Base64UrlDecode().GetString();
                string payloadJson   = parts[1].Base64UrlDecode().GetString();
                string signatureJson = parts[2].Base64UrlDecode().GetString();

                Dictionary <string, object> header = null;
                try
                {
                    header = JsonConvert.DeserializeObject <Dictionary <string, object> >(headerJson);
                    if (header == null)
                    {
                        return(false);
                    }
                }
                catch
                {
                    return(false);
                }

                JWTAlgorithm algorithm = JWTAlgorithm.Empty;
                if (header.ContainsKey("alg"))
                {
                    Enum.TryParse((string)header["alg"], out algorithm);
                }
                else
                {
                    return(false);
                }

                string signatureDecoded = HashSignature(algorithm, key.GetBytes(), $"{parts[0]}.{parts[1]}".GetBytes()).Base64UrlEncode();
                TimeSpan ts             = DateTime.Now.Subtract(startTime);
                Console.WriteLine($"=> Verifying took: {ts.Seconds}");

                if (signatureDecoded == parts[2])
                {
                    return(true);
                }
                return(false);
            });

            return(task);
        }
        public string DoCreate(string algorithm, PrivateClaims privateClaims, JWTOptions options)
        {
            this.error.cleanError();
            if (options.HasError())
            {
                this.error = options.GetError();
                return("");
            }
            JWTAlgorithm alg = JWTAlgorithmUtils.getJWTAlgorithm(algorithm, this.error);

            if (this.HasError())
            {
                return("");
            }
            if (this.HasError())
            {
                return("");
            }
            /***Hack to support 1024 RSA key lengths - BEGIN***/
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS256"] = 1024;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS512"] = 1024;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS384"] = 1024;
            /***Hack to support 1024 RSA key lengths - END***/

            /***Hack to support 192 ECDSA key lengths - BEGIN***/
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES256"] = 112;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES512"] = 112;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES384"] = 112;
            /***Hack to support 192 ECDSA key lengths - END***/

            JwtPayload payload = doBuildPayload(privateClaims, options);

            SecurityKey genericKey = null;

            if (JWTAlgorithmUtils.isPrivate(alg))
            {
                PrivateKeyManager key = options.GetPrivateKey();
                if (key.HasError())
                {
                    this.error = key.GetError();
                    return("");
                }
                if (SecurityUtils.compareStrings(key.getPrivateKeyAlgorithm(), "RSA"))
                {
                    try
                    {
                        genericKey = new RsaSecurityKey((RSA)key.getPrivateKeyForJWT());
                    }catch (Exception)
                    {
                        this.error = key.GetError();
                        return("");
                    }
                }
                else if (SecurityUtils.compareStrings(key.getPrivateKeyAlgorithm(), "ECDSA"))
                {
                    try {
                        genericKey = new ECDsaSecurityKey((ECDsa)key.getPrivateKeyForJWT());
                    }
                    catch (Exception)
                    {
                        this.error = key.GetError();
                        return("");
                    }
                }
                else
                {
                    this.error.setError("JW012", "Not recognized key algorithm");
                    return("");
                }
                if (genericKey == null)
                {
                    this.error = key.GetError();
                    return("");
                }
            }
            else
            {
                SymmetricSecurityKey symKey = new SymmetricSecurityKey(options.getSecret());
                genericKey = symKey;
            }

            SigningCredentials signingCredentials = JWTAlgorithmUtils.getSigningCredentials(alg, genericKey, this.error);

            if (this.HasError())
            {
                return("");
            }

            string signedJwt = "";

            try
            {
                JwtHeader header = new JwtHeader(signingCredentials);
                if (!options.GetHeaderParameters().IsEmpty())
                {
                    AddHeaderParameters(header, options);
                }

                JwtSecurityToken        secToken = new JwtSecurityToken(header, payload);
                JwtSecurityTokenHandler handler  = new JwtSecurityTokenHandler();
                signedJwt = handler.WriteToken(secToken);
            }
            catch (Exception e)
            {
                this.error.setError("JW003", "key size: " + /*genericKey.KeySize.ToString()*/ e.Message + e.StackTrace);

                return("");
            }

            return(signedJwt);
        }
        private bool DoVerify(string token, string expectedAlgorithm, PrivateClaims privateClaims, JWTOptions options, bool verifyClaims, bool verifyRegClaims)
        {
            this.error.cleanError();
            if (options.HasError())
            {
                this.error = options.GetError();
                return(false);
            }
            JWTAlgorithm expectedJWTAlgorithm = JWTAlgorithmUtils.getJWTAlgorithm(expectedAlgorithm, this.error);

            if (this.HasError())
            {
                return(false);
            }

            /***Hack to support 1024 RSA key lengths - BEGIN***/
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS256"] = 1024;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS512"] = 1024;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["RS384"] = 1024;
            /***Hack to support 1024 RSA key lengths - END***/

            /***Hack to support 192 ECDSA key lengths - BEGIN***/
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha256"] = 112;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha512"] = 112;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["EcdsaSha384"] = 112;
            /***Hack to support 192 ECDSA key lengths - END***/

            /***Hack to support 192 ECDSA key lengths - BEGIN***/
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES256"] = 112;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES512"] = 112;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap["ES384"] = 112;
            /***Hack to support 192 ECDSA key lengths - END***/


            JwtSecurityTokenHandler handler  = new JwtSecurityTokenHandler();
            JwtSecurityToken        jwtToken = new JwtSecurityToken(token);

            if (isRevoqued(jwtToken, options))
            {
                return(false);
            }
            if (verifyRegClaims)
            {
                if (!validateRegisteredClaims(jwtToken, options))
                {
                    return(false);
                }
            }
            if (verifyClaims)
            {
                if (!verifyPrivateClaims(jwtToken, privateClaims, options) || !VerifyHeader(jwtToken, options))
                {
                    return(false);
                }
            }
            //if validates all registered claims and it is not on revocation list
            TokenValidationParameters parms = new TokenValidationParameters();

            parms.ValidateLifetime = false;
            parms.ValidateAudience = false;
            parms.ValidateIssuer   = false;
            parms.ValidateActor    = false;
            JWTAlgorithm alg = JWTAlgorithmUtils.getJWTAlgorithm_forVerification(jwtToken.Header.Alg, this.error);

            if (this.HasError())
            {
                return(false);
            }
            if (JWTAlgorithmUtils.getJWTAlgorithm(jwtToken.Header.Alg, this.error) != expectedJWTAlgorithm || this.HasError())
            {
                this.error.setError("JW008", "Expected algorithm does not match token algorithm");
                return(false);
            }
            SecurityKey genericKey = null;

            if (JWTAlgorithmUtils.isPrivate(alg))
            {
                CertificateX509 cert = options.GetCertificate();
                if (cert.HasError())
                {
                    this.error = cert.GetError();
                    return(false);
                }
                if (SecurityUtils.compareStrings(cert.getPublicKeyAlgorithm(), "RSA"))
                {
                    try {
                        genericKey = new RsaSecurityKey((RSA)cert.getPublicKeyJWT());
                    }
                    catch (Exception)
                    {
                        this.error = cert.GetError();
                        return(false);
                    }
                }
                else if (SecurityUtils.compareStrings(cert.getPublicKeyAlgorithm(), "ECDSA"))
                {
                    try
                    {
                        genericKey = new ECDsaSecurityKey((ECDsa)cert.getPublicKeyJWT());
                    }
                    catch (Exception)
                    {
                        this.error = cert.GetError();
                        return(false);
                    }
                }
                else
                {
                    this.error.setError("JW013", "Not recognized key algorithm");
                    return(false);
                }
            }
            else
            {
                SymmetricSecurityKey symKey = new SymmetricSecurityKey(options.getSecret());
                genericKey = symKey;
            }
            genericKey.KeyId = "256";

            SigningCredentials signingCredentials = JWTAlgorithmUtils.getSigningCredentials(alg, genericKey, this.error);

            parms.IssuerSigningKey = genericKey;
            SecurityToken validatedToken;

            try
            {
                handler.ValidateToken(token, parms, out validatedToken);
            }
            catch (Exception e)
            {
                this.error.setError("JW004", e.Message);

                return(false);
            }
            return(true);
        }