.NET to CryptoAPI questions
- From: "Tom Carroll" <greyscale777@xxxxxxxxx>
- Date: 15 Dec 2005 12:07:45 -0800
I'm trying to encrypt and sign data in a .NET app, and then decrypt and
verify it in a Win32 app with CryptoAPI. I have verified going .NET to
..NET alright, but I'm running into some problems trying to use
CryptoAPI for the other side. I would really appreciate any help
anyone might have. The basic steps I'm doing are:
Preliminary - .NET:
- Make a new RSACryptoService provider with CspParameters flag
UseMachineKeyStore and a container name. I run this on both the .Net
app's machine with container name "MyNetServerKeys", and on the C++
app's machine with container name "MyCppServerKeys". So now each
computer has a key pair stored for it.
- On the C++ app's machine, I also do rsa.ToXmlString to export the
public key to an xml file, and transfer that file to the .NET app's
machine.
Preliminary C++:
-On the .NET app's machine, call CryptAcquireContext with
"MyNetServerKeys" and PROV_RSA_FULL and CRYPT_MACHINE_KEYSET to get the
key pair generated by .NET, and then CryptGetUserKey with
AT_KEYEXCHANGE, and then CryptExportKey with PUBLICKEYBLOB, then
transfer the publickeyblob file over to the C++ app's machine.
Now, in theory, each machine has its own private key and the other
machine's public key.
Encryption on .NET machine:
- Get the other machine's public key from the xml file and load it into
an RSACryptoServiceProvider.
- Call RSACryptoServiceProvider.Encrypt(data, false).
- Get a hash of the data using SHA1Managed.ComputeHash.
- Get machine's own private key from the container
- Use that with RSAPKCS1SignatureFormatter, hash alg "SHA1".
- Send the generated signature and the encrypted bytes to the C++ app.
Decryption on the C++ machine:
- Create new default handle with
CryptAcquireContext(handle,0,0,PROV_RSA_FULL,0)
- Get a hash of the encrypted data using CryptCreateHash with CALG_SHA1
(verified that the hash does in fact match what's generated in .NET)
- Load the other machine's public key from the public key blob with
CryptImportKey (seems to work ok; I verifired that its KP_ALGID is
CALG_RSA_KEYX, but not sure how to actually check the key's values
itself)
- Call CryptVerifySignature with the hash, key, and signature. (<--
FAILS with NTE_BAD_SIGNATURE)
- Create a new Crypto handle with CryptAcquireContext using the private
key container name and CRYPT_MACHINE_KEYSET
- Get the private key with CryptGetUserKey and AT_KEYEXCHANGE
- Call CryptDecrypt with the key and data (<-- FAILS with NTE_BAD_DATA)
So... does anyone have any ideas why the signature verification and
decryption are failing? I've seen some references to using
CspParameters.KeyNumber = 2 aka AT_SIGNATURE; do I have to do this all
the time? I don't really understand what the difference is, besides
that they are two different key pairs that live in the same container
and you need to pick one and stick with it. Should I specify a Crypto
Service Provider Name or something similar isntead of using the
defaults on both sides?
.
- Prev by Date: Is it possible to unsign a file
- Next by Date: Install AES CSP in Win2k and 98
- Previous by thread: Is it possible to unsign a file
- Next by thread: Install AES CSP in Win2k and 98
- Index(es):
Relevant Pages
|