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)); }
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 }
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); }
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)}"); }
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)); }