Azure Key Vault: Digital Signatures and Offline Verification
Explore using Digital Signatures with Azure Key Vault and how to verify signatures offline.
Table of Contents
Digital Signature is a mechanism to ensure the validity of a digital document or message. Digital signatures use asymmetric cryptography - uses a public and private key pair.
A valid digital signature gives a recipient reason to believe that the message was created by a known sender (authentication), that the sender cannot deny having sent the message (non-repudiation), and that the message was not altered in transit (integrity)
The below diagram shows the overview of the different steps involved in the Digital Signature process. We generate a hash of the data that we need to protect and encrypt the hash value using a private key pair. This signed hash is sent along with the original data. The receiver generates a hash of the data received and also decrypts the attached signature using the public key. If both the hashes are same, the signature is valid, and the document has not been tampered with.
Azure Key Vault supports sign and verify operations and can be used to implement Digital Signatures. In this post, we will explore how to sign and verify a message using Key Vault. Verifying the hash locally is the recommended approach as per the documentation and we will explore how this can be achieved.
Verification of signed hashes is supported as a convenience operation for applications that may not have access to [public] key material; it is recommended that, for best application performance, verify operations are performed locally.
Signing Data
Sign and Verify operations on Key Vault are allowed only on hashed data. So the application calling these API methods should locally hash the data before invoking the method. The algorithm property value passed to the Key Vault Client API depends on the hashing algorithm used to hash the data. Below are the supported algorithms.
- RS256: RSASSA-PKCS-v1_5 using SHA-256. The application supplied digest value must be computed using SHA-256 and must be 32 bytes in length.
- RS384: RSASSA-PKCS-v1_5 using SHA-384. The application supplied digest value must be computed using SHA-384 and must be 48 bytes in length.
- RS512: RSASSA-PKCS-v1_5 using SHA-512. The application supplied digest value must be computed using SHA-512 and must be 64 bytes in length.
- RSNULL: See [RFC2437], a specialized use-case to enable certain TLS scenarios.
The below code sample uses SHA-256 hashing algorithm to hash and sign the data.
var textToEncrypt = "This is a test message";
var byteData = Encoding.Unicode.GetBytes(textToEncrypt);
var hasher = new SHA256CryptoServiceProvider();
var digest = hasher.ComputeHash(byteData);
var signedResult = await keyVaultClient
.SignAsync(keyIdentifier, JsonWebKeySignatureAlgorithm.RS256, digest);
Verify Online
To verify a signature online, the keyVaultClient supports a Verify method. It takes the key identifier, algorithm, digest and signature to verify if the signature is valid for the given digest.
var isVerified = await keyVaultClient
.VerifyAsync(keyIdentifier, JsonWebKeySignatureAlgorithm.RS256, digest, signedResult.Result);
Verify Offline
To Verify offline, we need access to the public portion of the key used to sign the data. The client application that needs to verify signatures can connect to the vault and get the key details or use a public key shared out of band. The AD application used to authenticate with the key vault should have Get access for retrieving the public key from the vault. Get access can be set using the PermissionToKeys switch when registering the AD application with the key vault. Assuming we have access to the public key as a JSON string, we can use the [RSACryptoServiceProvider](https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider(v=vs.110).aspx) to verify the signature offline.
var key = JsonConvert.DeserializeObject<JsonWebKey>(jsonWebKey);
var rsa = new RSACryptoServiceProvider();
var p = new RSAParameters() { Modulus = key.N, Exponent = key.E };
rsa.ImportParameters(p);
isVerified = rsa.VerifyHash(digest, "Sha256", signedResult.Result);
The signature verification succeeds if the message and the signature were not tampered. If either of message or signature were modified then the signature validation fails.
You can get the sample code here. Hope this helps you to implement Digital Signatures using Key Vault.
Rahul Nath Newsletter
Join the newsletter to receive the latest updates in your inbox.