Example #1
0
        public void TestPublicKeyIsStoredInPemFormat()
        {
            var result = SigningKey.Create();

            Assert.IsTrue(result.PublicKey.StartsWith("-----BEGIN PUBLIC KEY-----\n"));
            Assert.IsTrue(result.PublicKey.EndsWith("-----END PUBLIC KEY-----\n"));
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation($"Worker running at {DateTime.Now}");
                var key      = SigningKey.Create();
                var response = await _metrics.KeyGenerationWorker().RecordTimeToSavePublicKey(async() => await SaveKey(key.PublicKey, stoppingToken));

                switch (response)
                {
                case KeyCreatedResponse createdResponse:
                    key.KeyId = createdResponse.Id;
                    _keyContainer.SetKey(key);
                    break;

                case ProblemDetails _:
                    _metrics.KeyGenerationWorker().MarkErrorSavingToKeyService();
                    _logger.LogError("problem while saving public key");
                    break;

                default:
                    _metrics.KeyGenerationWorker().MarkErrorUnhandledType();
                    _logger.LogError("unhandled type");
                    break;
                }

                await Task.Delay(TimeSpan.FromSeconds(_keyGenerationConfig.TimeBetweenGenerationInSeconds), stoppingToken);
            }
        }
Example #3
0
        public void TestThatIsValidReturnsFalseForInvalidSignatures()
        {
            var signingKey = new SigningKey("secret");
            var paymentCompletedResponse = PaymentCompletedResponse.CreateInstance("1", "CANCELLED", "ffb94fef027526bab3f98eaa432974daea4e743f09de86ab732208497805bb12", signingKey);

            Assert.IsNull(paymentCompletedResponse, "The given payment complete response was valid, but should be invalid");
        }
Example #4
0
 public void GetSigningKeyAsyncCallResultShouldBe(
     string signingKey)
 {
     _scenarioContext
     .GetCallResult <SigningKey>()
     .ShouldBe(SigningKey.Parse(signingKey));
 }
Example #5
0
        protected async Task <IActionResult> GenerateJWTToken(TUser user)
        {
            var rolesAndScopes = await AuthenticationHelper.GetRolesAndScopesAsync(user, _userManager, _roleManager);

            var roles  = rolesAndScopes.Roles;
            var scopes = rolesAndScopes.Scopes;

            if (!string.IsNullOrWhiteSpace(_privateSigningKeyPath))
            {
                var key     = SigningKey.LoadPrivateRsaSigningKey(_privateSigningKeyPath);
                var results = JwtTokenHelper.CreateJwtTokenSigningWithRsaSecurityKey(user.Id, user.UserName, user.Email, roles, _tokenExpiryMinutes, key, _localIssuer, _audience, scopes.ToArray());
                return(Created("", results));
            }
            else if (!string.IsNullOrWhiteSpace(_privateSigningCertificatePassword))
            {
                var key     = SigningKey.LoadPrivateSigningCertificate(_privateSigningCertificatePath, _privateSigningCertificatePassword);
                var results = JwtTokenHelper.CreateJwtTokenSigningWithCertificateSecurityKey(user.Id, user.UserName, user.Email, roles, _tokenExpiryMinutes, key, _localIssuer, _audience, scopes.ToArray());
                return(Created("", results));
            }
            else
            {
                var key     = SigningKey.LoadSymmetricSecurityKey(_privateSymmetricKey);
                var results = JwtTokenHelper.CreateJwtTokenSigningWithKey(user.Id, user.UserName, user.Email, roles, _tokenExpiryMinutes, key, _localIssuer, _audience, scopes.ToArray());
                return(Created("", results));
            }
        }
Example #6
0
        internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg)
        {
            // Authorize results in a REPLACEMENT not an extend of the previous policy.
            var     zeroHash = new TpmHash(hashAlg);
            TpmHash atEnd    = PolicyUpdate(zeroHash, TpmCc.PolicyAuthorize, SigningKey.GetName(), PolicyRef);

            return(atEnd);
        }
 public bool Equals(BusinessKey other)
 {
     if (other == null)
     {
         return(false);
     }
     return(ClientId.Equals(other.ClientId) && SigningKey.Equals(other.SigningKey));
 }
Example #8
0
        public void TestCreateReturnsPrivateAndPublicKey()
        {
            var result = SigningKey.Create();

            Assert.NotNull(result.PrivateKey);
            Assert.NotNull(result.PublicKey);
            Assert.NotNull(result.CreatedAt);
        }
Example #9
0
        public void TestThatLettersinOrderIdIsValid()
        {
            var signingKey = new SigningKey("secret");
            var paymentCompletedResponse = PaymentCompletedResponse.CreateInstance("Test1234", "COMPLETED", "bf4f5b787d954296b9c2e15028c2311df5e31a3d94c540e361faf1d0951b7858041089d430e17730f1efd3a308881c094355f55e09b993ca53f2063859d1eb4b", signingKey);

            Assert.IsNotNull(paymentCompletedResponse);
            Assert.AreEqual("Test1234", paymentCompletedResponse.OrderId);
            Assert.AreEqual("COMPLETED", paymentCompletedResponse.Status);
        }
Example #10
0
        public void TestThatIsValidReturnsTrueForAValidSignature()
        {
            var signingKey = new SigningKey("secret");
            var paymentCompletedResponse = PaymentCompletedResponse.CreateInstance("1", "COMPLETED", "b890b2f3c6f102bb853ed448dd58d2c13cc695541f5eecca713470e68ced6f2c1a5f5ddd529a732ff51a019126ffefa8bd1d0193b596b393339ffcbf6f335241", signingKey);

            Assert.IsNotNull(paymentCompletedResponse);
            Assert.AreEqual("1", paymentCompletedResponse.OrderId);
            Assert.AreEqual("COMPLETED", paymentCompletedResponse.Status);
        }
Example #11
0
        public void TestThatIsValidReturnsTrueForUnderscoreInStatus()
        {
            var signingKey = new SigningKey("secret");
            var paymentCompletedResponse = PaymentCompletedResponse.CreateInstance("1", "IN_PROGRESS", "1a551027bc3cc041a56b9efa252640c76b2e5815f816dd123fa1b32b4683729e904b5fa711870b956f1d9b16c714168d129068a48f875c2f91185d6c18eccf61", signingKey);

            Assert.IsNotNull(paymentCompletedResponse);
            Assert.AreEqual("1", paymentCompletedResponse.OrderId);
            Assert.AreEqual("IN_PROGRESS", paymentCompletedResponse.Status);
        }
        public void TestCalculateBase64EncodedKey()
        {
            var signingKey = new SigningKey(Convert.FromBase64String("AHwD9V0BWrG8I39BnWmcQQ=="));

            var left = new SignableSpy(new List <string> {
                "", "foo", "", "bar", ""
            });

            Assert.AreEqual(left.GetCalculatedSignature(signingKey), "de414646b65ac54f045716e5e79e3b5ab2d78db1e5e5bd24e9c2c8e87ad21c2795814d7a0a551b7fc8c3cb75cbcc62ca556078a10f4591ba48025fe9096786ee");
        }
 public void Dispose()
 {
     if (SigningKey != null)
     {
         SigningKey.Dispose();
     }
     if (EncryptionKey != null)
     {
         EncryptionKey.Dispose();
     }
 }
Example #14
0
 public Task VASPSetItsContractSigningKeyTo(
     string signingKey)
 {
     return(_scenarioContext
            .GetContractByType <VASPContract>()
            .SetSigningKey
            (
                owner: _accounts.Owner,
                signingKey: SigningKey.Parse(signingKey)
            ));
 }
Example #15
0
 public async Task VASPSetItsContractSigningKeyTo(
     string signingKey)
 {
     await _scenarioContext
     .GetContractByType <VASPContract>()
     .SetSigningKeyAsync
     (
         owner: await _accounts.GetOwnerAsync(),
         signingKey: SigningKey.Parse(signingKey)
     );
 }
Example #16
0
        public static T CreateInstance <T>(string json, SigningKey signingKey) where T : Response
        {
            if (string.IsNullOrWhiteSpace(json))
            {
                return(default(T));
            }

            var response = JsonHelper.Deserialize <T>(json);

            response.ValidateSignature(signingKey);
            return(response);
        }
Example #17
0
        public OmniKassaApiClient(string refreshToken, string signingKey, bool testMode = false)
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            var tokenProvider = new InMemoryTokenProvider(refreshToken);

            if (testMode)
            {
                _baseUrl += "-sandbox";
            }
            _baseUrl   += "/";
            _connector  = new ApiConnector(new HttpClientRestTemplate(_baseUrl), tokenProvider);
            _signingKey = new SigningKey(Convert.FromBase64String(signingKey));
        }
        public void TestCalculateSignatureNullIsEmptyString()
        {
            var signingKey = new SigningKey("testKey");

            var left = new SignableSpy(new List <string> {
                null, "foo", null, "bar", null
            });
            var right = new SignableSpy(new List <string> {
                "", "foo", "", "bar", ""
            });

            Assert.AreEqual(left.GetCalculatedSignature(signingKey), right.GetCalculatedSignature(signingKey));
        }
Example #19
0
        public PrivateKey(string label, bool eighteenByteRipe = false)
        {
            var startTime = DateTime.Now;

            Label = label;

            RNGCryptoServiceProvider rnd = new RNGCryptoServiceProvider();

            byte[] potentialPrivSigningKey = new byte[32];
            rnd.GetBytes(potentialPrivSigningKey);
            SigningKey = ECDSA.PointMult(potentialPrivSigningKey);

            int numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0;

            byte[] ripemd160;
            byte[] potentialPrivEncryptionKey = new byte[32];

            while (true)
            {
                numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1;
                rnd.GetBytes(potentialPrivEncryptionKey);

                EncryptionKey = ECDSA.PointMult(potentialPrivEncryptionKey);

                byte[] buff = SigningKey.Concatenate(EncryptionKey);
                byte[] sha  = new SHA512Managed().ComputeHash(buff);
                ripemd160 = RIPEMD160.Create().ComputeHash(sha);

                if (eighteenByteRipe)
                {
                    if ((ripemd160[0] == 0) && (ripemd160[1] == 0))
                    {
                        break;
                    }
                }
                else
                {
                    if (ripemd160[0] == 0)
                    {
                        break;
                    }
                }
            }

            // NonceTrialsPerByte используется значение по умолчанию
            // payloadLengthExtraBytes используется значение по умолчанию
            PrivSigningKeyWif    = PrivateKey2Wif(potentialPrivSigningKey);
            PrivEncryptionKeyWif = PrivateKey2Wif(potentialPrivEncryptionKey);

            Status = Status.Valid;
        }
        protected async Task <IActionResult> GenerateJWTToken(TUser user)
        {
            //Add roles
            var roles = await _userManager.GetRolesAsync(user);

            var scopes = (await _userManager.GetClaimsAsync(user)).Where(c => c.Type == "scope").Select(c => c.Value).ToHashSet();

            var ownerRole = await _roleManager.FindByNameAsync("authenticated");

            if (ownerRole != null)
            {
                var roleScopes = (await _roleManager.GetClaimsAsync(ownerRole)).Where(c => c.Type == "scope").Select(c => c.Value).ToList();
                foreach (var scope in roleScopes)
                {
                    scopes.Add(scope);
                }
            }

            //Add role scopes.
            foreach (var roleName in roles)
            {
                var role = await _roleManager.FindByNameAsync(roleName);

                if (role != null)
                {
                    var roleScopes = (await _roleManager.GetClaimsAsync(role)).Where(c => c.Type == "scope").Select(c => c.Value).ToList();
                    foreach (var scope in roleScopes)
                    {
                        scopes.Add(scope);
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(_privateSigningKeyPath))
            {
                var key     = SigningKey.LoadPrivateRsaSigningKey(_privateSigningKeyPath);
                var results = JwtTokenHelper.CreateJwtTokenSigningWithRsaSecurityKey(user.Id, user.UserName, roles, _tokenExpiryMinutes, key, _localIssuer, "api", scopes.ToArray());
                return(Created("", results));
            }
            else if (!string.IsNullOrWhiteSpace(_privateSigningCertificatePassword))
            {
                var key     = SigningKey.LoadPrivateSigningCertificate(_privateSigningCertificatePassword, _privateSigningCertificatePassword);
                var results = JwtTokenHelper.CreateJwtTokenSigningWithCertificateSecurityKey(user.Id, user.UserName, roles, _tokenExpiryMinutes, key, _localIssuer, "api", scopes.ToArray());
                return(Created("", results));
            }
            else
            {
                var results = JwtTokenHelper.CreateJwtTokenSigningWithKey(user.Id, user.UserName, roles, _tokenExpiryMinutes, _privateSymmetricKey, _localIssuer, "api", scopes.ToArray());
                return(Created("", results));
            }
        }
        public void TestCalculateBase64EncodedVsTextKey()
        {
            var leftKey = new SigningKey(Convert.FromBase64String("c2VjcmV0"));
            var left    = new SignableSpy(new List <string> {
                "", "foo", "", "bar", ""
            });

            var rightKey = new SigningKey("secret");
            var right    = new SignableSpy(new List <string> {
                "", "foo", "", "bar", ""
            });

            Assert.AreEqual(left.GetCalculatedSignature(leftKey), right.GetCalculatedSignature(rightKey));
        }
        public void TestCalculateSignatureDifferentKey()
        {
            var left = new SignableSpy(new List <string> {
                "foo", "bar"
            });
            var leftKey = new SigningKey("testKey1");

            var right = new SignableSpy(new List <string> {
                "foo", "bar"
            });
            var rightKey = new SigningKey("testKey2");

            Assert.AreNotEqual(left.GetCalculatedSignature(leftKey), right.GetCalculatedSignature(rightKey));
        }
Example #23
0
        public static void AddJwtCookieAuthentication(this IServiceCollection services,
                                                      string secret_key, string issuer = "NC", string audience = "NCUser")
        {
            var tokenValidationParameters = new TokenValidationParameters
            {
                // The signing key must match!
                ValidateIssuerSigningKey = true,
                IssuerSigningKey         = SigningKey.GetSigningKey(secret_key),

                // Validate the JWT Issuer (iss) claim
                ValidateIssuer = true,
                ValidIssuer    = issuer,

                // Validate the JWT Audience (aud) claim
                ValidateAudience = true,
                ValidAudience    = audience,

                // Validate the token expiry
                ValidateLifetime = true,

                // If you want to allow a certain amount of clock drift, set that here:
                ClockSkew = TimeSpan.Zero
            };

            services.AddAuthentication(o =>
            {
                o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                o.DefaultChallengeScheme    = CookieAuthenticationDefaults.AuthenticationScheme;
                o.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
            }
                                       ).AddCookie((options) => {
                options.Cookie.Name      = "access_token";
                options.Cookie.HttpOnly  = true;
                options.TicketDataFormat = new CustomJwtDataFormat(
                    SecurityAlgorithms.HmacSha256,
                    tokenValidationParameters);
                options.Events.OnRedirectToAccessDenied = (context) =>
                {
                    return(Task.Run(() =>
                    {
                        context.Response.StatusCode = 401;
                    }));
                };
                options.Events.OnRedirectToLogin = (context) => {
                    return(Task.Run(() => {
                        context.Response.StatusCode = 401;
                    }));
                };
            });
        }
Example #24
0
        public void TestCreateJwt()
        {
            var keyContainer = new Mock <IKeyContainer>();
            var mockOptions  = new Mock <IOptions <IdentityOptions> >();

            mockOptions.Setup(x => x.Value).Returns(new IdentityOptions
            {
                ClaimsIdentity = new ClaimsIdentityOptions
                {
                    SecurityStampClaimType = "security"
                }
            });
            var key = SigningKey.Create();

            key.KeyId = "keyId";
            keyContainer.Setup(x => x.GetKey()).Returns(key);
            var mockIdentityConfigOption = new Mock <IOptions <IdentityConfig> >();

            mockIdentityConfigOption.Setup(x => x.Value).Returns(new IdentityConfig
            {
                Audiences = new List <string> {
                    "aud1", "aud2"
                },
                Issuer           = "auth_test",
                IssueForAudience = "issuer"
            });
            var tokenFactory = new TokenFactory(keyContainer.Object, mockOptions.Object, mockIdentityConfigOption.Object);
            var claims       = new []
            {
                new Claim("name", "Alice"),
                new Claim("role", "sudo"),
                new Claim("security", "secure_data"),
            };
            var claimsPrincipal = new Mock <ClaimsPrincipal>();

            claimsPrincipal.Setup(x => x.Claims).Returns(claims);

            var handler = new JwtSecurityTokenHandler();
            var token   = handler.ReadJwtToken(tokenFactory.GenerateJwtToken(claimsPrincipal.Object));

            Assert.AreEqual("keyId", token.Header.Kid);
            Assert.AreEqual("Alice", token.Claims.FirstOrDefault(x => x.Type == "name")?.Value);
            Assert.AreEqual("sudo", token.Claims.FirstOrDefault(x => x.Type == "role")?.Value);
            Assert.IsNull(token.Claims.FirstOrDefault(x => x.Type == "security")?.Value);
        }
Example #25
0
    protected void Page_Load(object sender, EventArgs e)
    {
        var orderId    = Request.QueryString["order_id"];
        var status     = Request.QueryString["status"];
        var signature  = Request.QueryString["signature"];
        var signingKey = new SigningKey(Convert.FromBase64String(WebConfigurationManager.AppSettings["SigningKey"]));
        var paymentCompletedResponse = PaymentCompletedResponse.CreateInstance(orderId, status, signature, signingKey);

        if (paymentCompletedResponse == null)
        {
            throw new Exception("The payment completed response was invalid.");
        }

        // Use these variables instead of using the URL parameters ($orderId and $status). Input validation has been performed on these values.
        var validatedMerchantOrderId = paymentCompletedResponse.OrderId;
        var validatedStatus          = paymentCompletedResponse.Status;
        // ... complete payment
    }
Example #26
0
    public static byte[] CreateSigningKeyMaterial(string userSecretsId, string scheme, string issuer, int signingKeyLength = 32, bool reset = false)
    {
        // Create signing material and save to user secrets
        var newKeyMaterial  = System.Security.Cryptography.RandomNumberGenerator.GetBytes(signingKeyLength);
        var secretsFilePath = PathHelper.GetSecretsPathFromSecretsId(userSecretsId);

        Directory.CreateDirectory(Path.GetDirectoryName(secretsFilePath));

        JsonObject secrets = null;

        if (File.Exists(secretsFilePath))
        {
            using var secretsFileStream = new FileStream(secretsFilePath, FileMode.Open, FileAccess.Read);
            if (secretsFileStream.Length > 0)
            {
                secrets = JsonSerializer.Deserialize <JsonObject>(secretsFileStream);
            }
        }

        secrets ??= new JsonObject();
        var signkingKeysPropertyName = GetSigningKeyPropertyName(scheme);
        var shortId = Guid.NewGuid().ToString("N").Substring(0, 8);
        var key     = new SigningKey(shortId, issuer, Convert.ToBase64String(newKeyMaterial), signingKeyLength);

        if (secrets.ContainsKey(signkingKeysPropertyName))
        {
            var signingKeys = secrets[signkingKeysPropertyName].AsArray();
            if (reset)
            {
                var toRemove = signingKeys.SingleOrDefault(key => key["Issuer"].GetValue <string>() == issuer);
                signingKeys.Remove(toRemove);
            }
            signingKeys.Add(key);
        }
        else
        {
            secrets.Add(signkingKeysPropertyName, JsonValue.Create(new[] { key }));
        }

        using var secretsWriteStream = new FileStream(secretsFilePath, FileMode.Create, FileAccess.Write);
        JsonSerializer.Serialize(secretsWriteStream, secrets);

        return(newKeyMaterial);
    }
        private void addTokenInCookie(HttpClient httpClient, string username, string[] roles,
                                      string cookieDomain,
                                      IList <KeyValuePair <string, string> > claims,
                                      string secretKey,
                                      string audience, string issuer)
        {
            httpClient.DefaultRequestHeaders.Remove("Cookie");
            var signingKey = SigningKey.GetSigningKey(secretKey);
            var options    = new TokenProviderOptions
            {
                Audience           = audience,
                Issuer             = issuer,
                SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
            };
            var jwtService = new JwtService();

            JsonWebToken token;

            if (claims != null)
            {
                claims.Add(new KeyValuePair <string, string>("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", username));
                token = jwtService.GenerateJsonWebToken(username, roles, options, claims.ToArray());
            }
            else
            {
                token = jwtService.GenerateJsonWebToken(username, roles, options, new KeyValuePair <string, string>("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", username));
            }


            var cookieOptions = new CookieOptions
            {
                Domain  = cookieDomain,
                Expires = DateTimeOffset.UtcNow.AddHours(8).AddDays(1).AddMinutes(-5)
            };

            var cookies = new List <string> {
                $"access_token={token.AccessToken}",
                $"username={username}",
                $"expires_in={token.ExpiresIn}"
            };

            httpClient.DefaultRequestHeaders.Add("Cookie", string.Join(";", cookies));
        }
        private async Task <Address> InnerCreateVASPContractAsync(
            Address vaspContractCreator,
            VASPCode vaspCode,
            Address vaspContractOwner,
            Channels channels,
            TransportKey transportKey,
            MessageKey messageKey,
            SigningKey signingKey)
        {
            var contract = Web3.Eth.GetContract(ABI, RealAddress);
            var function = contract.GetFunction("createVASPContract");

            var functionInput = new object[]
            {
                (byte[])vaspCode,
                (string)vaspContractOwner,
                (byte[])channels,
                (byte[])transportKey,
                (byte[])messageKey,
                (byte[])signingKey
            };

            var receipt = await function.SendTransactionAndWaitForReceiptAsync
                          (
                @from : vaspContractCreator,
                gas : await function.EstimateGasAsync(functionInput),
                value : new HexBigInteger(0),
                receiptRequestCancellationToken : null,
                functionInput : functionInput
                          );

            return(Address.Parse
                   (
                       receipt.Logs[5]["topics"][2]
                       .ToString()
                       .Replace
                       (
                           "0x000000000000000000000000",
                           "0x",
                           System.StringComparison.OrdinalIgnoreCase
                       )
                   ));
        }
Example #29
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    _logger.LogInformation($"Worker running at {DateTime.Now}");

                    try
                    {
                        var key      = SigningKey.Create();
                        var response = await SaveKey(key.PublicKey, stoppingToken);

                        switch (response)
                        {
                        case KeyCreatedResponse createdResponse:
                            key.KeyId = createdResponse.Id;
                            _signatureKeyContainer.Key = key;
                            break;

                        case ProblemDetails p:
                            throw new Exception($"{p.Status} {p.TitleProperty} {p.Detail}");

                        default:
                            throw new Exception("unhandled error");
                        }

                        await Task.Delay(TimeSpan.FromSeconds(_config.SignatureTtl - 30), stoppingToken);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "failed to obtain signature key");
                        await Task.Delay(TimeSpan.FromSeconds(5));
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "caught exception");
                    await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
                }
            }
        }
        public void TestCalculateSignatureDifferentData()
        {
            var signingKey = new SigningKey("testKey");

            var left = new SignableSpy(new List <string> {
                "Foo", "Bar"
            });
            var right = new SignableSpy(new List <string> {
                "foo", "bar"
            });

            Assert.AreNotEqual(left.GetCalculatedSignature(signingKey), right.GetCalculatedSignature(signingKey));

            left = new SignableSpy(new List <string> {
                "foo ", "bar "
            });
            right = new SignableSpy(new List <string> {
                "foo", "bar"
            });

            Assert.AreNotEqual(left.GetCalculatedSignature(signingKey), right.GetCalculatedSignature(signingKey));

            left = new SignableSpy(new List <string> {
                " foo", " bar"
            });
            right = new SignableSpy(new List <string> {
                "foo", "bar"
            });

            Assert.AreNotEqual(left.GetCalculatedSignature(signingKey), right.GetCalculatedSignature(signingKey));

            left = new SignableSpy(new List <string> {
                "bar", "foo"
            });
            right = new SignableSpy(new List <string> {
                "foo", "bar"
            });

            Assert.AreNotEqual(left.GetCalculatedSignature(signingKey), right.GetCalculatedSignature(signingKey));
        }