Short question: Is the D parameter of the RSA alghorithm crypthographically strong enough to be used as a secret key for generating SHA-256 hash value?

Long question: I'm working on windows platform. I have to protect certain data with HMAC. I have 4 servers that need to be able to generate/validate hmac values for certain data.

I'm using this class to generate the HMAC value - https://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha256(v=vs.110).aspx

It requires secret. Obviously the secret needs to be shared among all 4 servers. I have a requirement to protect this secret. It can't be stored as a plain text file.

It's fine for certain key custodian to access this secret but not for wider audience e.g. system maintainers/developers.

I thought I might use windows certificate store as a mechanism that protects the key. The idea is following

Key custodian generates a self signed certificate, installs it in the certificate store on each of the 4 servers. After cert is installed the key custodian grants access to the certificate and private key to a "system user" that hosts the application. This is done on each server.

The cert is retrieved as needed by application and private private key extracted and then D value of that private key is fed into hmac calculator as shared secret.

    private byte[] ExtractPrivateKeyFromCertificate(X509Certificate2 certificate)
        var provider = certificate.PrivateKey as RSACryptoServiceProvider;
        var privateKey = provider?.ExportParameters(true);

        if (privateKey != null)
            var value = privateKey.Value;
            return value.D;
            throw new ArgumentException("Certificate does not contain a private key", nameof(certificate));

then that is passed into the Hmac calculator

var hmac = new HMACSHA256(ExtractPrivateKeyFromCertificate(certificate));

and hash is calculated


Do not do this. No, it's not ok.

What you're looking for is to protect the integrity of some message. You would like to use HMAC, which is the correct algorithm. The question is: how to link up RSA and HMAC and all messages.

You should use standard Public Key Signing.

  1. Generate a random HMAC Key (size is the same as the size of the hash used for HMAC).
  2. Compute HMAC(Message,Key_HMAC).
  3. Compute Sign(HMAC,Key_RSA).

Package Message||Key_HMAC||Signature and distribute as needed.

To check integrity, recompute HMAC and verify signature over it.

Every server sharing the same self signed Signing certificate is OK. Or, you could create a root certificate and provision four Signing certificates each signed by the root cert, one per server. If you properly sign the message and package it in a PKCS envelope, the server that signed it will package it's certificate with the signature and each server can separately verify the signature as it trusts the root of the attached certificate. This may take up a lot of space (PKI signature can be large) per signed message.

  • Thank you for your suggestion. It feels much mores secure variation. I feel I should have shared the other constraints that I have. I'm dealing with stringent SLA requirements and can't afford to do hmac + PKI signing due to extra time it would take to do that... so PKI signing isn't an option for me. Also as you pointed out PKI signature ads few kb to each record and I have 40 million records. Normally you could say storage is cheap but in my situation there's 0 data loos requirements and I have 2 geo located high priced datacenters and storage is at premium, so size is also a problem – ambidexterous Nov 26 '15 at 21:31
  • Can you elaborate why you're suggesting that I don't do this. There are lot of other security features in place in this solution this particular one is just for data integrity... to ensure that people who have access to db and don't have access to app servers can't mess up the data. What exactly seems problematic with this approach the strength of the key is not good enough in your opinion? – ambidexterous Nov 26 '15 at 21:36
  • You can't just throw algorithms together, misuse them and hope their security attributes apply (like sprinkling Asymmetric Crypto Keys over data and believing this means something). The Private Key in RSA isn't for your proposed purpose. You might as well just generate a Secret Key (of size HMAC), share that across machines and use that. I suggest you create a new question which includes your system layout, all of your requirements including Integrity protection, don't propose a specific algorithm (not this one) although outlining your ideas is fine, and then see how people answer. – Andrew Philips Nov 26 '15 at 21:49
  • Ok, you're saying "You might as well just generate a Secret Key (of size HMAC), share that across machines and use that." - correct I could do that, but then I wouldn't be able to use Certificate store as a convenient mechanism to do that sharing. The part I'm solving with using D parameter of the RSA key is "share that across machines". I consider a cert store much more secure way of doing this sharing than something like plain text file... – ambidexterous Nov 29 '15 at 2:04
  • I was wondering if doing something like this would make more sense: 1. generate strong Secret Key(of size HMAC), encrypt the key using RSA (e.g. encrypt it with the cert) store the encrypted value of the HMAC key on a settings file on each app server. (without the access to the private key of the cert that value in settings file will be useless) 2. when application loads decrypt the key and store in a safe protected memory location and use the key as usual. 3. when it's time to regenerate the keys - regenerate the certificate, generate new HMAC, encrypt with new certificate – ambidexterous Nov 29 '15 at 2:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.