예제 #1
0
        private async Task <string> SignAndCreateJwtAsync(JwtSecurityToken jwt)
        {
            var algorithm = "RS256";//jwt.SignatureAlgorithm;

            var plaintext = $"{jwt.EncodedHeader}.{jwt.EncodedPayload}";

            byte[] hash;
            using (var hasher = CryptoHelper.GetHashAlgorithmForSigningAlgorithm(algorithm))
            {
                hash = hasher.ComputeHash(Encoding.UTF8.GetBytes(plaintext));
            }

            var cryptoClient = new CryptographyClient(
                new Uri("https://cleankey.vault.azure.net/keys/cleankey/82f7ce0323574ab4869565d3bc525793"),
                new DefaultAzureCredential());

            try
            {
                //jwt.SignatureAlgorithm
                var signResult = await cryptoClient.SignAsync(new SignatureAlgorithm(algorithm), hash);

                return($"{plaintext}.{Base64UrlTextEncoder.Encode(signResult.Signature)}");
            }
            catch (Exception ex)
            {
                return(ex.Message);
            }
        }
        public async Task SignLocalVerifyRoundTripFramework([Fields(nameof(SignatureAlgorithm.PS256), nameof(SignatureAlgorithm.PS384), nameof(SignatureAlgorithm.PS512))] SignatureAlgorithm algorithm)
        {
#if !NETFRAMEWORK
            // RSA-PSS is not supported on .NET Framework so recorded tests will fall back to the remote client.
            Assert.Ignore("RSA-PSS is supported on .NET Core so local tests will pass. This test method is to test that on .NET Framework RSA-PSS sign/verify attempts fall back to the remote client.");
#endif

            Key key = await CreateTestKey(algorithm);

            RegisterForCleanup(key.Name);

            CryptographyClient client = GetCryptoClient(key.Properties.Id);

            byte[] data = new byte[32];
            Recording.Random.NextBytes(data);

            using HashAlgorithm hashAlgo = algorithm.GetHashAlgorithm();
            byte[] digest = hashAlgo.ComputeHash(data);

            // Should sign remotely...
            SignResult signResult = await client.SignAsync(algorithm, digest);

            Assert.AreEqual(algorithm, signResult.Algorithm);
            Assert.AreEqual(key.KeyMaterial.KeyId, signResult.KeyId);
            Assert.NotNull(signResult.Signature);

            // ...and verify locally.
            VerifyResult verifyResult = await client.VerifyAsync(algorithm, digest, signResult.Signature);

            Assert.AreEqual(algorithm, verifyResult.Algorithm);
            Assert.AreEqual(key.KeyMaterial.KeyId, verifyResult.KeyId);
            Assert.IsTrue(verifyResult.IsValid);
        }
        public async Task SignLocalVerifyRoundTrip([Fields(nameof(SignatureAlgorithm.ES256), nameof(SignatureAlgorithm.ES384), nameof(SignatureAlgorithm.ES512))] SignatureAlgorithm algorithm)
        {
            Key key = await CreateTestKey(algorithm);

            RegisterForCleanup(key);

            CryptographyClient client = GetCryptoClient(key.Id);

            byte[] data = new byte[32];
            Recording.Random.NextBytes(data);

            using HashAlgorithm hashAlgo = algorithm.GetHashAlgorithm();
            byte[] digest = hashAlgo.ComputeHash(data);

            // Should sign remotely...
            SignResult signResult = await client.SignAsync(algorithm, digest);

            Assert.AreEqual(algorithm, signResult.Algorithm);
            Assert.AreEqual(key.KeyMaterial.KeyId, signResult.KeyId);
            Assert.NotNull(signResult.Signature);

            // ...and verify locally.
            VerifyResult verifyResult = await client.VerifyAsync(algorithm, digest, signResult.Signature);

            Assert.AreEqual(algorithm, verifyResult.Algorithm);
            Assert.AreEqual(key.KeyMaterial.KeyId, verifyResult.KeyId);
            Assert.IsTrue(verifyResult.IsValid);
        }
        public void SignAlgorithmNotSupported([EnumValues(Exclude = new[] { nameof(KeyType.Rsa), nameof(KeyType.RsaHsm), nameof(KeyType.Ec), nameof(KeyType.EcHsm) })] KeyType keyType)
        {
            JsonWebKey         jwk    = CreateKey(keyType);
            CryptographyClient client = CreateClient <CryptographyClient>(jwk);

            Assert.ThrowsAsync <NotSupportedException>(async() => await client.SignAsync(new SignatureAlgorithm("ignored"), TestData));
        }
        public void SignOperationNotSupported()
        {
            JsonWebKey         jwk    = new JsonWebKey(RSA.Create(), keyOps: Array.Empty <KeyOperation>());
            CryptographyClient client = CreateClient <CryptographyClient>(jwk);

            Assert.ThrowsAsync <NotSupportedException>(async() => await client.SignAsync(new SignatureAlgorithm("ignored"), TestData));
        }
예제 #6
0
        public override async Task RunAsync(CancellationToken cancellationToken)
        {
            SignResult result = await CryptographyClient.SignAsync(s_algorithm, _digest);

            byte[] signature = result.Signature;

#if DEBUG
            Assert.AreEqual(256, signature.Length);
#endif
        }
예제 #7
0
            private async Task <(string token, string body)> SignRequestAsync(object request)
            {
                var body = JsonConvert.SerializeObject(request);

                using var hasher = SHA512.Create();
                var bytes = hasher.ComputeHash(Encoding.UTF8.GetBytes(body));

                var signature = await _cryptoClient.SignAsync(SignatureAlgorithm.RS512, bytes);

                return(Convert.ToBase64String(signature.Signature), body);
            }
        public async Task SignVerifyRoundtrip([EnumValues(Exclude = new[] { nameof(SignatureAlgorithm.PS256), nameof(SignatureAlgorithm.PS384), nameof(SignatureAlgorithm.PS512) })] SignatureAlgorithm algorithm)
        {
            JsonWebKey         jwk    = KeyUtilities.CreateKey(algorithm, includePrivateParameters: true);
            CryptographyClient client = CreateClient <CryptographyClient>(jwk);

            byte[]     digest = algorithm.GetHashAlgorithm().ComputeHash(TestData);
            SignResult signed = await client.SignAsync(algorithm, digest);

            VerifyResult verified = await client.VerifyAsync(algorithm, digest, signed.Signature);

            Assert.IsTrue(verified.IsValid);
        }
        public async Task SignVerifyDataStreamRoundTrip([Fields] SignatureAlgorithm algorithm)
        {
            Key key = await CreateTestKey(algorithm);

            CryptographyClient cryptoClient = GetCryptoClient(key.Id);

            var data = new byte[8000];

            Recording.Random.NextBytes(data);

            using MemoryStream dataStream = new MemoryStream(data);

            using HashAlgorithm hashAlgo = algorithm.GetHashAlgorithm();

            byte[] digest = hashAlgo.ComputeHash(dataStream);

            dataStream.Seek(0, SeekOrigin.Begin);

            SignResult signResult = await cryptoClient.SignAsync(algorithm, digest);

            SignResult signDataResult = await cryptoClient.SignDataAsync(algorithm, dataStream);

            Assert.AreEqual(algorithm, signResult.Algorithm);
            Assert.AreEqual(algorithm, signDataResult.Algorithm);

            Assert.AreEqual(key.Id, signResult.KeyId);
            Assert.AreEqual(key.Id, signDataResult.KeyId);

            Assert.NotNull(signResult.Signature);
            Assert.NotNull(signDataResult.Signature);

            dataStream.Seek(0, SeekOrigin.Begin);

            VerifyResult verifyResult = await cryptoClient.VerifyAsync(algorithm, digest, signDataResult.Signature);

            VerifyResult verifyDataResult = await cryptoClient.VerifyDataAsync(algorithm, dataStream, signResult.Signature);

            Assert.AreEqual(algorithm, verifyResult.Algorithm);
            Assert.AreEqual(algorithm, verifyDataResult.Algorithm);

            Assert.AreEqual(key.Id, verifyResult.KeyId);
            Assert.AreEqual(key.Id, verifyDataResult.KeyId);

            Assert.True(verifyResult.IsValid);
            Assert.True(verifyResult.IsValid);

            RegisterForCleanup(key);
        }
        public async Task SignLocalVerifyRoundTrip([Fields(Exclude = new[] { nameof(SignatureAlgorithm.ES256K) })] SignatureAlgorithm algorithm)
        {
#if NET461
            if (algorithm.GetEcKeyCurveName() != default)
            {
                Assert.Ignore("Creating JsonWebKey with ECDsa is not supported on net461.");
            }
#endif

#if NETFRAMEWORK
            if (algorithm.GetRsaSignaturePadding() == RSASignaturePadding.Pss)
            {
                Assert.Ignore("RSA-PSS signature padding is not supported on .NET Framework.");
            }
#endif

            Key key = await CreateTestKey(algorithm);

            RegisterForCleanup(key.Name);

            CryptographyClient client = GetCryptoClient(key.Id);

            byte[] data = new byte[32];
            Recording.Random.NextBytes(data);

            using HashAlgorithm hashAlgo = algorithm.GetHashAlgorithm();
            byte[] digest = hashAlgo.ComputeHash(data);

            // Should sign remotely...
            SignResult signResult = await client.SignAsync(algorithm, digest);

            Assert.AreEqual(algorithm, signResult.Algorithm);
            Assert.AreEqual(key.KeyMaterial.KeyId, signResult.KeyId);
            Assert.NotNull(signResult.Signature);

            // ...and verify locally.
            VerifyResult verifyResult = await client.VerifyAsync(algorithm, digest, signResult.Signature);

            Assert.AreEqual(algorithm, verifyResult.Algorithm);
            Assert.AreEqual(key.KeyMaterial.KeyId, verifyResult.KeyId);
            Assert.IsTrue(verifyResult.IsValid);
        }
        public async Task SignVerifyDataRoundTrip([Fields] SignatureAlgorithm algorithm)
        {
            Key key = await CreateTestKey(algorithm);

            RegisterForCleanup(key.Name);

            CryptographyClient cryptoClient = GetCryptoClient(key.Id, forceRemote: true);

            byte[] data = new byte[32];
            Recording.Random.NextBytes(data);

            using HashAlgorithm hashAlgo = algorithm.GetHashAlgorithm();

            byte[] digest = hashAlgo.ComputeHash(data);

            SignResult signResult = await cryptoClient.SignAsync(algorithm, digest);

            SignResult signDataResult = await cryptoClient.SignDataAsync(algorithm, data);

            Assert.AreEqual(algorithm, signResult.Algorithm);
            Assert.AreEqual(algorithm, signDataResult.Algorithm);

            Assert.AreEqual(key.Id, signResult.KeyId);
            Assert.AreEqual(key.Id, signDataResult.KeyId);

            Assert.NotNull(signResult.Signature);
            Assert.NotNull(signDataResult.Signature);

            VerifyResult verifyResult = await cryptoClient.VerifyAsync(algorithm, digest, signDataResult.Signature);

            VerifyResult verifyDataResult = await cryptoClient.VerifyDataAsync(algorithm, data, signResult.Signature);

            Assert.AreEqual(algorithm, verifyResult.Algorithm);
            Assert.AreEqual(algorithm, verifyDataResult.Algorithm);

            Assert.AreEqual(key.Id, verifyResult.KeyId);
            Assert.AreEqual(key.Id, verifyDataResult.KeyId);

            Assert.True(verifyResult.IsValid);
            Assert.True(verifyResult.IsValid);
        }
예제 #12
0
        protected override async Task <string> CreateJwtAsync(JwtSecurityToken jwt)
        {
            var plaintext = $"{jwt.EncodedHeader}.{jwt.EncodedPayload}";

            byte[] hash;
            using (var hasher = CryptoHelper.GetHashAlgorithmForSigningAlgorithm(jwt.SignatureAlgorithm))
            {
                hash = hasher.ComputeHash(Encoding.UTF8.GetBytes(plaintext));
            }

            var cryptoClient = new CryptographyClient(
                new Uri(""), // e.g. https://scottbrady91-test.vault.azure.net/keys/IdentityServerSigningKeyEcc
                new ClientSecretCredential(
                    tenantId: "",
                    clientId: "",
                    clientSecret: ""));

            var signResult = await cryptoClient.SignAsync(new SignatureAlgorithm(jwt.SignatureAlgorithm), hash);

            return($"{plaintext}.{Base64UrlTextEncoder.Encode(signResult.Signature)}");
        }
예제 #13
0
        public async Task SignVerifyAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            // Instantiate a key client that will be used to create a key. Notice that the client is using default Azure
            // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            var keyClient = new KeyClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // First we'll create both a RSA key and an EC which will be used to sign and verify
            string rsaKeyName = $"CloudRsaKey-{Guid.NewGuid()}";
            var    rsaKey     = new CreateRsaKeyOptions(rsaKeyName, hardwareProtected: false)
            {
                KeySize = 2048,
            };

            string ecKeyName = $"CloudEcKey-{Guid.NewGuid()}";
            var    ecKey     = new CreateEcKeyOptions(ecKeyName, hardwareProtected: false)
            {
                CurveName = KeyCurveName.P256K,
            };

            KeyVaultKey cloudRsaKey = await keyClient.CreateRsaKeyAsync(rsaKey);

            Debug.WriteLine($"Key is returned with name {cloudRsaKey.Name} and type {cloudRsaKey.KeyType}");

            KeyVaultKey cloudEcKey = await keyClient.CreateEcKeyAsync(ecKey);

            Debug.WriteLine($"Key is returned with name {cloudEcKey.Name} and type {cloudEcKey.KeyType}");

            // Let's create the CryptographyClient which can perform cryptographic operations with the keys we just created.
            // Again we are using the default Azure credential as above.
            var rsaCryptoClient = new CryptographyClient(cloudRsaKey.Id, new DefaultAzureCredential());

            var ecCryptoClient = new CryptographyClient(cloudEcKey.Id, new DefaultAzureCredential());

            // Next we'll sign some arbitrary data and verify the signatures using the CryptographyClient with both the EC and RSA keys we created.
            byte[] data   = Encoding.UTF8.GetBytes("This is some sample data which we will use to demonstrate sign and verify");
            byte[] digest = null;

            //
            // Signing with the SignAsync and VerifyAsync methods
            //

            // The SignAsync and VerifyAsync methods expect a precalculated digest, and the digest needs to be calculated using the hash algorithm which matches the
            // singature algorithm being used. SHA256 is the hash algorithm used for both RS256 and ES256K which are the algorithms we'll be using in this sample
            using (HashAlgorithm hashAlgo = SHA256.Create())
            {
                digest = hashAlgo.ComputeHash(data);
            }

            // Get the signature for the computed digest with both keys. Note that the signature algorithm specified must be a valid algorithm for the key type,
            // and for EC keys the algorithm must also match the curve of the key
            SignResult rsaSignResult = await rsaCryptoClient.SignAsync(SignatureAlgorithm.RS256, digest);

            Debug.WriteLine($"Signed digest using the algorithm {rsaSignResult.Algorithm}, with key {rsaSignResult.KeyId}. The resulting signature is {Convert.ToBase64String(rsaSignResult.Signature)}");

            SignResult ecSignResult = await ecCryptoClient.SignAsync(SignatureAlgorithm.ES256K, digest);

            Debug.WriteLine($"Signed digest using the algorithm {ecSignResult.Algorithm}, with key {ecSignResult.KeyId}. The resulting signature is {Convert.ToBase64String(ecSignResult.Signature)}");

            // Verify the signatures
            VerifyResult rsaVerifyResult = await rsaCryptoClient.VerifyAsync(SignatureAlgorithm.RS256, digest, rsaSignResult.Signature);

            Debug.WriteLine($"Verified the signature using the algorithm {rsaVerifyResult.Algorithm}, with key {rsaVerifyResult.KeyId}. Signature is valid: {rsaVerifyResult.IsValid}");

            VerifyResult ecVerifyResult = await ecCryptoClient.VerifyAsync(SignatureAlgorithm.ES256K, digest, ecSignResult.Signature);

            Debug.WriteLine($"Verified the signature using the algorithm {ecVerifyResult.Algorithm}, with key {ecVerifyResult.KeyId}. Signature is valid: {ecVerifyResult.IsValid}");

            //
            // Signing with the SignDataAsync and VerifyDataAsync methods
            //

            // The SignDataAsync and VerifyDataAsync methods take the raw data which is to be signed.  The calculate the digest for the user so there is no need to compute the digest

            // Get the signature for the data with both keys. Note that the signature algorithm specified must be a valid algorithm for the key type,
            // and for EC keys the algorithm must also match the curve of the key
            SignResult rsaSignDataResult = await rsaCryptoClient.SignDataAsync(SignatureAlgorithm.RS256, data);

            Debug.WriteLine($"Signed data using the algorithm {rsaSignDataResult.Algorithm}, with key {rsaSignDataResult.KeyId}. The resulting signature is {Convert.ToBase64String(rsaSignDataResult.Signature)}");

            SignResult ecSignDataResult = await ecCryptoClient.SignDataAsync(SignatureAlgorithm.ES256K, data);

            Debug.WriteLine($"Signed data using the algorithm {ecSignDataResult.Algorithm}, with key {ecSignDataResult.KeyId}. The resulting signature is {Convert.ToBase64String(ecSignDataResult.Signature)}");

            // Verify the signatures
            VerifyResult rsaVerifyDataResult = await rsaCryptoClient.VerifyDataAsync(SignatureAlgorithm.RS256, data, rsaSignDataResult.Signature);

            Debug.WriteLine($"Verified the signature using the algorithm {rsaVerifyDataResult.Algorithm}, with key {rsaVerifyDataResult.KeyId}. Signature is valid: {rsaVerifyDataResult.IsValid}");

            VerifyResult ecVerifyDataResult = await ecCryptoClient.VerifyDataAsync(SignatureAlgorithm.ES256K, data, ecSignDataResult.Signature);

            Debug.WriteLine($"Verified the signature using the algorithm {ecVerifyDataResult.Algorithm}, with key {ecVerifyDataResult.KeyId}. Signature is valid: {ecVerifyDataResult.IsValid}");

            // The Cloud Keys are no longer needed, need to delete them from the Key Vault.
            DeleteKeyOperation rsaKeyOperation = await keyClient.StartDeleteKeyAsync(rsaKeyName);

            DeleteKeyOperation ecKeyOperation = await keyClient.StartDeleteKeyAsync(ecKeyName);

            // To ensure the key is deleted on server before we try to purge it.
            Task.WaitAll(
                rsaKeyOperation.WaitForCompletionAsync().AsTask(),
                ecKeyOperation.WaitForCompletionAsync().AsTask());

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted keys needs to be purged.
            Task.WaitAll(
                keyClient.PurgeDeletedKeyAsync(rsaKeyName),
                keyClient.PurgeDeletedKeyAsync(ecKeyName));
        }
        public void SignRequiresPrivateKey([EnumValues] SignatureAlgorithm algorithm)
        {
            JsonWebKey         jwk    = KeyUtilities.CreateKey(algorithm, keyOps: new[] { KeyOperation.Sign, KeyOperation.Verify });
            CryptographyClient client = CreateClient <CryptographyClient>(jwk);

            byte[] digest = algorithm.GetHashAlgorithm().ComputeHash(TestData);
            Assert.ThrowsAsync(new InstanceOfTypeConstraint(typeof(CryptographicException)), async() => await client.SignAsync(algorithm, digest));
        }