Reputation: 12485
I'm trying to import an RSA public/private key pair generated with the Win32 Crypto API into a .NET application. The code that creates and exports the key pair looks something like this:
// Abbreviated for clarity.
CryptAcquireContext(..., MS_ENHANCED_PROV, ...);
// Generate public/private key pair
CryptCreateHash(..., CALG_SHA1, ...);
CryptHashData(hash, password, ...);
CryptDeriveKey(..., CALG_3DES, hash, CRYPT_EXPORTABLE, ...);
CyrptExportKey(..., derivedKey, PRIVATEKEYBLOB, ...);
Basically, this code is exporting the public/private key pair as an encrypted blob. It uses the 3DES algorithm for the encryption with a key derived from a SHA-1 hash.
Now, when I try to import this key into .NET, I get problems. I've tried to approaches:
(1) I create an RSACyrptoServiceProvider object and call ImportCspBlob(). This throws an exception with the message "bad data." That's not surprising since the provider object has no way to know how the blob was encrypted. As far as I can tell, there's no way at all to tell it what algorithm and key to use for this.
(2) I manually decrypt the blob myself, using the PasswordDeriveBytes class, and then pass the decrypted blob to ImportCsbBlob(). Once again, I get an exception. This time the message is "bad version of provider." I tried manually supplying the provider name ("Microsoft Enhanced Cryptographic Provider v1.0") when creating the provider object, but it makes no difference.
It's critical that I get this working. Any ideas?
SOLUTION
After generating the unencrypted public/private key pairs in both C++ and .NET, I discovered that the Microsoft Enhanced Cryptographic Provider does not actually encrypt the first 8-bytes of the key pair. (This must be the versioning information that was throwing the .NET wrapper for a loop.) After modifying my .NET decryption code to leave the first 8 bytes alone, everything works fine.
This solution isn't very good since it depends on internal implementation detials of the cryptographic provider. Unfortunately, I don't think there's any other way since Microsoft neglected to provide a version of ImportCspBlob that lets you specify an algorithm and key for decryption.
Upvotes: 2
Views: 3172
Reputation: 273244
In approach 2), verify the decrypted key is the same as before encryption.
I don't think "a key derived from a SHA-1 hash" will match one from PasswordDeriveBytes
Upvotes: 2