.NET to CryptoAPI questions



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?

.



Relevant Pages

  • Re: Regarding encryption and Decryption
    ... CAPICOM (which leverages most of useful underlying CryptoAPI capability) ... If you encrypt arbitrary data, you will be using a secret *symmetric* key to ... access that encryption key so your users can decrypt your encrypted content. ... I will distribute the public key. ...
    (microsoft.public.security)
  • Re: Protecting assemblies from being used outside a company/group/team
    ... verification, but it sounds like you have something else in mind. ... > assemblies here at all. ... > Encrypt something to send the server which can decrypt with its private ... > this does require you have some confidence in the public key your using. ...
    (microsoft.public.dotnet.security)
  • Re: Protecting assemblies from being used outside a company/group/team
    ... I embedded the public key token so that I can check it at runtime. ... You would probably want to also encrypt the key token string using ... > verification, but it sounds like you have something else in mind. ... >> assemblies here at all. ...
    (microsoft.public.dotnet.security)
  • Re: how to have a gpg public key?
    ... Having just a public key doesn't do you much good. ... You need both a private key and a public key; ... can encrypt and decrypt your messages and you are just ...
    (Debian-User)
  • Re: Using CryptoAPI to do a DH key exchange with OpenSSL
    ... a struct for the OpenSSL DH key blob format? ... But so far, CryptoAPI has gotten ... start to figure out what's the data difference between CAPI and OpenSSL ... the DH public key format in CAPI. ...
    (microsoft.public.platformsdk.security)