public void CanReadToken_WhenTokenIsNullOrWhitespace_ExpectFalse(string token)
        {
            var handler      = new BrancaTokenHandler();
            var canReadToken = handler.CanReadToken(token);

            canReadToken.Should().BeFalse();
        }
        public void ValidateToken_WhenTokenCannotBeRead_ExpectFailureWithSecurityTokenException()
        {
            var result = new BrancaTokenHandler().ValidateToken("=====", new TokenValidationParameters());

            result.IsValid.Should().BeFalse();
            result.Exception.Should().BeOfType <SecurityTokenException>();
        }
        public void ValidateToken_WhenTokenIsNullOrWhitespace_ExpectFailureWithArgumentNullException(string token)
        {
            var result = new BrancaTokenHandler().ValidateToken(token, new TokenValidationParameters());

            result.IsValid.Should().BeFalse();
            result.Exception.Should().BeOfType <ArgumentNullException>();
        }
        public void ValidateToken_WhenTokenValidationParametersAreNull_ExpectFailureWithArgumentNullException()
        {
            var result = new BrancaTokenHandler().ValidateToken(ValidToken, null);

            result.IsValid.Should().BeFalse();
            result.Exception.Should().BeOfType <ArgumentNullException>();
        }
        public void CanReadToken_WhenJwtToken_ExpectFalse()
        {
            const string jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiU2NvdHQgQnJhZHkiLCJpYXQiOjE1ODU3Njc0Mjl9.DcGCOpx19JQzVVeZPHgqB73rbLaCUsx-k6PuFdit6IM";

            var canReadToken = new BrancaTokenHandler().CanReadToken(jwt);

            canReadToken.Should().BeFalse();
        }
        public void CanReadToken_WhenTokenContainsNonBase64Characters_ExpectFalse()
        {
            const string token = "token==";

            var canReadToken = new BrancaTokenHandler().CanReadToken(token);

            canReadToken.Should().BeFalse();
        }
示例#7
0
        public void ValidateToken_TestTokenWithWrongVersion()
        {
            const string token = "89mvl3RkwXjpEj5WMxK7GUDEHEeeeZtwjMIOogTthvr44qBfYtQSIZH5MHOTC0GzoutDIeoPVZk3w";

            var handler   = new BrancaTokenHandler();
            var exception = Assert.Throws <SecurityTokenException>(() => handler.DecryptToken(token, key));

            exception.Message.Should().Be("Unsupported Branca version");
        }
示例#8
0
        public void ValidateToken_TestTokenWithEightNullBytesAndMaxTimestamp()
        {
            const string token = "1jrx6DUq9HmXvYdmhWMhXzx3klRzhlAjsc3tUFxDPCvZZLm16GYOzsBG4KwF1djjW1yTeZ2B";

            var handler        = new BrancaTokenHandler();
            var decryptedToken = handler.DecryptToken(token, key);

            decryptedToken.Payload.Should().Be(System.Text.Encoding.UTF8.GetString(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }));
            decryptedToken.Timestamp.Should().Be(DateTimeOffset.FromUnixTimeSeconds(4294967295).UtcDateTime);
        }
示例#9
0
        public void ValidateToken_TestTokenWithEightNullBytesAndZeroTimestamp()
        {
            const string token = "1jIBheHWEwYIP59Wpm4QkjkIKuhc12NcYdp9Y60B6av7sZc3vJ5wBwmKJyQzGfJCrvuBgGnf";

            var handler        = new BrancaTokenHandler();
            var decryptedToken = handler.DecryptToken(token, key);

            decryptedToken.Payload.Should().Be(System.Text.Encoding.UTF8.GetString(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }));
            decryptedToken.Timestamp.Should().Be(DateTimeOffset.FromUnixTimeSeconds(0).UtcDateTime);
        }
示例#10
0
        public void ValidateToken_TestTokenWithHelloWorldAndNovember27Timestamp()
        {
            const string token = "875GH234UdXU6PkYq8g7tIM80XapDQOH72bU48YJ7SK1iHiLkrqT8Mly7P59TebOxCyQeqpMJ0a7a";

            var handler        = new BrancaTokenHandler();
            var decryptedToken = handler.DecryptToken(token, key);

            decryptedToken.Payload.Should().Be("Hello world!");
            decryptedToken.Timestamp.Should().Be(DateTimeOffset.FromUnixTimeSeconds(123206400).UtcDateTime);
        }
示例#11
0
        public void ValidateToken_TestTokenWithHelloWorldAndMaxTimestamp()
        {
            const string token = "89i7YCwtsSiYfXvOKlgkCyElnGCOEYG7zLCjUp4MuDIZGbkKJgt79Sts9RdW2Yo4imonXsILmqtNb";

            var handler        = new BrancaTokenHandler();
            var decryptedToken = handler.DecryptToken(token, key);

            decryptedToken.Payload.Should().Be("Hello world!");
            decryptedToken.Timestamp.Should().Be(DateTimeOffset.FromUnixTimeSeconds(4294967295).UtcDateTime);
        }
示例#12
0
        public void ValidateToken_TestTokenWithHelloWorldAndZeroTimestamp()
        {
            const string token = "870S4BYjk7NvyViEjUNsTEmGXbARAX9PamXZg0b3JyeIdGyZkFJhNsOQW6m0K9KnXt3ZUBqDB6hF4";

            var handler        = new BrancaTokenHandler();
            var decryptedToken = handler.DecryptToken(token, key);

            decryptedToken.Payload.Should().Be("Hello world!");
            decryptedToken.Timestamp.Should().Be(DateTimeOffset.FromUnixTimeSeconds(0).UtcDateTime);
        }
        public void CanReadToken_WhenTokenIsTooLong_ExpectFalse()
        {
            var tokenBytes = new byte[TokenValidationParameters.DefaultMaximumTokenSizeInBytes + 1];

            new Random().NextBytes(tokenBytes);

            var canReadToken = new BrancaTokenHandler().CanReadToken(Convert.ToBase64String(tokenBytes));

            canReadToken.Should().BeFalse();
        }
示例#14
0
        public void ValidateToken_TestTokenWithEightNullBytesAndNovember27Timestamp()
        {
            const string token = "1jJDJOEfuc4uBJh5ivaadjo6UaBZJDZ1NsWixVCz2mXw3824JRDQZIgflRqCNKz6yC7a0JKC";

            var handler        = new BrancaTokenHandler();
            var decryptedToken = handler.DecryptToken(token, key);

            decryptedToken.Payload.Should().Be(System.Text.Encoding.UTF8.GetString(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }));
            decryptedToken.Timestamp.Should().Be(DateTimeOffset.FromUnixTimeSeconds(123206400).UtcDateTime);
        }
示例#15
0
        public void ValidateToken_CiphertextModification_ExpectSecurityTokenException()
        {
            var handler = new BrancaTokenHandler();

            var token   = handler.CreateToken("test", key);
            var decoded = Base62.Decode(token);

            decoded[decoded.Length - 17] ^= 1; // Last byte before the Poly1305 tag

            Assert.Throws <CryptographicException>(() => handler.DecryptToken(Base62.Encode(decoded), key));
        }
        public void CreateToken_WhenTokenGenerated_ExpectBas62EncodedTokenWithCorrectLength()
        {
            var payload = Guid.NewGuid().ToString();
            var handler = new BrancaTokenHandler();

            var token = handler.CreateToken(payload, validKey);

            token.Any(x => !Base62.CharacterSet.Contains(x)).Should().BeFalse();
            Base62.Decode(token).Length.Should().Be(
                System.Text.Encoding.UTF8.GetBytes(payload).Length + 29 + 16);
        }
        public void EnryptAndDecryptToken_ExpectCorrectPayloadAndTimestamp()
        {
            var payload = Guid.NewGuid().ToString();
            var handler = new BrancaTokenHandler();

            var token            = handler.CreateToken(payload, validKey);
            var decryptedPayload = handler.DecryptToken(token, validKey);

            decryptedPayload.Payload.Should().Be(payload);
            decryptedPayload.Timestamp.Should().BeCloseTo(DateTime.UtcNow, 1000);
        }
        public void EnryptAndDecryptToken_WithExplicitTimestamp_ExpectCorrectPayloadAndTimestamp()
        {
            var payload   = Guid.NewGuid().ToString();
            var timestamp = new DateTime(2020, 08, 22).ToUniversalTime();
            var handler   = new BrancaTokenHandler();

            var token            = handler.CreateToken(payload, timestamp, validKey);
            var decryptedPayload = handler.DecryptToken(token, validKey);

            decryptedPayload.Payload.Should().Be(payload);
            decryptedPayload.Timestamp.Should().Be(timestamp);
        }
        public void EnryptAndDecryptToken_WithExplicitBrancaTimestamp_ExpectCorrectPayloadAndTimestamp()
        {
            var payload   = Guid.NewGuid().ToString();
            var timestamp = uint.MinValue;
            var handler   = new BrancaTokenHandler();

            var token            = handler.CreateToken(payload, timestamp, validKey);
            var decryptedPayload = handler.DecryptToken(token, validKey);

            decryptedPayload.Payload.Should().Be(payload);
            decryptedPayload.Timestamp.Should().Be(new DateTime(1970, 01, 01, 0, 0, 0, DateTimeKind.Utc));
            decryptedPayload.BrancaFormatTimestamp.Should().Be(timestamp);
        }
示例#20
0
        public void ValidateToken_WhenTokenPayloadIsNotJson_ExpectFailureWithArgumentException()
        {
            const string tokenWithInvalidPayload = "9FvacDjvxjhWG5cqkP3WBrIb6cuCBl9sPjJvkrGX0XI8tbLJQe6Pb2EcbeyOGkbextBqDdHa66pF0HBMg";

            var result = new BrancaTokenHandler().ValidateToken(
                tokenWithInvalidPayload,
                new TokenValidationParameters {
                TokenDecryptionKey = new SymmetricSecurityKey(validKey)
            });

            result.IsValid.Should().BeFalse();
            result.Exception.Should().BeOfType <ArgumentException>();
        }
        public void ValidateToken_WhenTokenPayloadIsNotJson_ExpectFailureWithArgumentException()
        {
            const string tokenWithInvalidPayload = "Mvm6wbsyZMgClkmtiBf0lW3rEkvnCK5RgytoerJJex40b9yqh6GbSlfkFJHgFX9ocF";

            var result = new BrancaTokenHandler().ValidateToken(
                tokenWithInvalidPayload,
                new TokenValidationParameters {
                TokenDecryptionKey = new SymmetricSecurityKey(validKey)
            });

            result.IsValid.Should().BeFalse();
            result.Exception.Should().BeOfType <ArgumentException>();
        }
        public void ValidateToken_WhenIncorrectDecryptionKey_ExpectFailureWithSecurityTokenDecryptionFailedException()
        {
            var key = new byte[32];

            new Random().NextBytes(key);

            var result = new BrancaTokenHandler().ValidateToken(
                ValidToken,
                new TokenValidationParameters {
                TokenDecryptionKey = new SymmetricSecurityKey(key)
            });

            result.IsValid.Should().BeFalse();
            result.Exception.Should().BeOfType <SecurityTokenDecryptionFailedException>();
        }
        public void CreateAndDecryptToken_WithSecurityTokenDescriptor_ExpectCorrectBrancaTimestampAndNoIatClaim()
        {
            var handler = new BrancaTokenHandler();

            var token = handler.CreateToken(new SecurityTokenDescriptor
            {
                EncryptingCredentials = new EncryptingCredentials(new SymmetricSecurityKey(validKey), ExtendedSecurityAlgorithms.XChaCha20Poly1305)
            });

            var parsedToken = handler.DecryptToken(token, validKey);
            var jObject     = JObject.Parse(parsedToken.Payload);

            jObject["iat"].Should().BeNull();

            parsedToken.Timestamp.Should().BeCloseTo(DateTime.UtcNow, 1000);
        }
        public void CreateAndValidateToken_WithSecurityTokenDescriptor_ExpectCorrectBrancaTimestampAndNoIatClaim()
        {
            const string issuer    = "me";
            const string audience  = "you";
            const string subject   = "123";
            var          expires   = DateTime.UtcNow.AddDays(1);
            var          notBefore = DateTime.UtcNow;

            var handler = new BrancaTokenHandler();

            var token = handler.CreateToken(new SecurityTokenDescriptor
            {
                Issuer    = issuer,
                Audience  = audience,
                Expires   = expires,
                NotBefore = notBefore,
                Claims    = new Dictionary <string, object> {
                    { "sub", subject }
                },
                EncryptingCredentials = new EncryptingCredentials(new SymmetricSecurityKey(validKey), ExtendedSecurityAlgorithms.XChaCha20Poly1305)
            });

            var validatedToken = handler.ValidateToken(token, new TokenValidationParameters
            {
                ValidIssuer        = issuer,
                ValidAudience      = audience,
                TokenDecryptionKey = new SymmetricSecurityKey(validKey)
            });

            validatedToken.IsValid.Should().BeTrue();
            validatedToken.ClaimsIdentity.Claims.Should().Contain(
                x => x.Type == "sub" && x.Value == subject);

            var brancaToken = (BrancaSecurityToken)validatedToken.SecurityToken;

            brancaToken.Issuer.Should().Be(issuer);
            brancaToken.Audiences.Should().Contain(audience);
            brancaToken.Subject.Should().Be(subject);
            brancaToken.IssuedAt.Should().BeWithin(1.Minutes()).After(notBefore);
            brancaToken.ValidFrom.Should().BeWithin(0.Seconds()).After(notBefore);
            brancaToken.ValidTo.Should().BeWithin(0.Seconds()).After(expires);
        }
示例#25
0
        public IActionResult Branca()
        {
            var handler = new BrancaTokenHandler();

            var token = handler.CreateToken(new SecurityTokenDescriptor
            {
                Issuer   = "me",
                Audience = "you",
                EncryptingCredentials = options.BrancaEncryptingCredentials
            });

            var parsedToken = handler.DecryptToken(token, ((SymmetricSecurityKey)options.BrancaEncryptingCredentials.Key).Key);

            return(View("Index", new TokenModel
            {
                Type = "Branca",
                Token = token,
                Payload = parsedToken.Payload
            }));
        }
示例#26
0
        public Result <BrancaToken> Decrypt(string key, string keyType, string token)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (string.IsNullOrWhiteSpace(keyType))
            {
                throw new ArgumentNullException(nameof(keyType));
            }
            if (string.IsNullOrWhiteSpace(token))
            {
                throw new ArgumentNullException(nameof(token));
            }

            byte[] keyBytes;
            try
            {
                keyBytes = ParseKey(key, keyType);
            }
            catch
            {
                return(Result <BrancaToken> .Failure("Unable to parse key"));
            }

            if (keyBytes.Length != 32)
            {
                return(Result <BrancaToken> .Failure("Invalid key length"));
            }

            var handler = new BrancaTokenHandler();

            try
            {
                return(Result <BrancaToken> .Success(handler.DecryptToken(token, keyBytes)));
            }
            catch
            {
                return(Result <BrancaToken> .Failure("Unable to decrypt token"));
            }
        }
示例#27
0
        public Result <string> Encrypt(string key, string keyType, uint timestamp, string payload)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (string.IsNullOrWhiteSpace(keyType))
            {
                throw new ArgumentNullException(nameof(keyType));
            }
            if (string.IsNullOrWhiteSpace(payload))
            {
                throw new ArgumentNullException(nameof(payload));
            }

            byte[] keyBytes;
            try
            {
                keyBytes = ParseKey(key, keyType);
            }
            catch
            {
                return(Result <string> .Failure("Unable to parse key"));
            }

            if (keyBytes.Length != 32)
            {
                return(Result <string> .Failure("Invalid key length"));
            }

            var handler = new BrancaTokenHandler();

            try
            {
                return(Result <string> .Success(handler.CreateToken(payload, timestamp, keyBytes)));
            }
            catch
            {
                return(Result <string> .Failure("Unable to create token"));
            }
        }
        public void CreateToken_WhenPayloadIsNullOrWhitespace_ExpectArgumentNullException(string payload)
        {
            var handler = new BrancaTokenHandler();

            Assert.Throws <ArgumentNullException>(() => handler.CreateToken(payload, validKey));
        }
        public void CanReadToken_WhenBrancaToken_ExpectTrue()
        {
            var canReadToken = new BrancaTokenHandler().CanReadToken(ValidToken);

            canReadToken.Should().BeTrue();
        }
        public void DecryptToken_WhenValidToken_ExpectCorrectPayload()
        {
            var parsedToken = new BrancaTokenHandler().DecryptToken(ValidToken, validKey);

            parsedToken.Payload.Should().Be(ExpectedPayload);
        }