.net and CryptoAPI key information

From: Michel Gallant (neutron_at_istar.ca)
Date: 09/15/03


Date: Mon, 15 Sep 2003 16:12:08 -0400


The follwoing information is updated from previous post.

.NET crypto can make use of the underlying CryptoAPI persistent key
storage (key container) infrastructure, but the documentation:
 "Generating Keys for Encryption and Decryption":
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcongeneratingkeysforencryptiondecryption.asp
is not very clear on some details.

The following information may be useful to those with some CryptoAPI
background:

- default RSACryptoServiceProvider rsa = RSACryptoServiceProvider() constructor
  generates new RSA public/private transient key-pair each time invoked.

- if rsa.PersistKeyInCsp = true is used with the default RSACryptoServiceProvider
  constructor, a random key container name, prepended with "CLR" is persisted to
  protected CryptoAPI key storage.

- overloaded RSACryptoServiceProvider rsa = RSACryptoServiceProvider(CspParameters cp)
  creates (or reuses an existing) a persistent key container with the name specified
  in cp.KeyContainerName

- for this overloaded constructor, if the only CspParameters field specified is
  KeyContainerName, the RSA key-pair generated (or re-used) is the key pair of
  type AT_KEYEXCHANGE (compare below to Strong Name generated keypairs AT_SIGNATURE).
  CryptoAPI key containers associated with the MS CSPs can contain
  two types of key-pairs (key spec): AT_KEYEXCHANGE and AT_SIGNATURE which the
  WinCrypt.h header file defines as 1 and 2 respectively.

 - although not clearly documented, it appears that the key type is specified
  using the property: CspParameters.KeyNumber with:
     CspParameters.KeyNumber= 1 (AT_KEYEXCHANGE)
     CspParameters.KeyNumber= 2 (AT_SIGNATURE)
  and with AT_EXCHANGE being the default KeyNumber value.

 - if a RSACryptoServiceProvider is instantiated twice, once with KeyNumber=1 and then
   2, supplying the same cp.KeyContainerName, then the same CryptoAPI keycontainer
   will be populated with 2 sets of keys in the same named key container. These keypairs
   have different public/private key values. This is similar to the PSDK sample code
   for generating a key container with both Signature and Exchange key pairs:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/example_c_program_creating_a_key_container_and_generating_keys.asp
The Strong Name tool sn.exe, when used to generate key-pairs and pass them to a
keycontainer, generates AT_SIGNATURE keys only (.NET 1.0/1.1), and currently
Strong-Name'ing only supports AT_SIGNATURE keys. Therefore, any key-container
keys generated via .NET with default RSACryptoServiceProvider(CspParameters cp),
which is AT_KEYEXCHANGE, will fail when attempting to Strong-Name sign.

CryptoAPI, encoded and .NET Public Keys:
-----------------------------------------
The term "public key blob" is used a bit loosely in docs.
This should help clarify:

(1)The CryptoAPI "Public Key Blob" as defined/described at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/public_key_blobs.asp
is NOT an ASN.1 encoded key structure. Key modulus and exponent
are stored in little-endian order.

(2) The "Public Key" viewable in any of:
     Certificate properties panel
     .NET X509Certificate.GetPublicKey(
     CAPICOM oCert.PublicKey().EncodedKey
are identical ASN.1 encoded key public key values. Key modulus and exponent
are stored in big-endian order.

(3) The public key embedded in assembly meta-data by strong-naming, and viewable by:
     Ildasm.exe as assembly manifest metadata ".publickey = (.."
     sn.exe -e
     sn.exe -p
     secutil.exe -s
are identical. This public key representation is a shallow "wrapper" around
the CryptoAPI Public Key Blob, (1) above, as defined in the strongname.h file
with signature algorithm, hash algorithm and remaining (CryptoAPI) blob size.

For a given public key, all representations above include the same public key modulus,
key exponent plus other details particular to the representation.

For example, the following shows the byte-size of each public key format above,
for an RSA 1024 bit key pair:
  CryptoAPI public key blob: 148 bytes
  ASN Encoded pub. key blob: 140 bytes
  .NET strong-name public key: 160 bytes (12 bytes + 148 byte-CryptoAPI blob)

CryptoAPI PRIVATEKEYBLOB and .NET keypair files:
------------------------------------------------
When .NET keypairs are generated using Strong Name tool:
  sn.exe -k "mysigkeys.snk"
a new keyfile holding a new randomly generated 1024 bit
RSA AT_SIGNATURE keypair is created.
The format of this file is an unencrypted CryptoAPI PUBLICKEYBLOB:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/private_key_blobs.asp
and therefore needs to be carefully protected.

 - Michel Gallant
   MVP Security
   http://pages.istar.ca/~neutron



Relevant Pages

  • 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)
  • Re: Using CryptoAPI to do a DH key exchange with OpenSSL
    ... But so far, CryptoAPI has gotten ... start to figure out what's the data difference between CAPI and OpenSSL ... to cryptoapi obviously doesn't include the blob header info. So I ... the DH public key format in CAPI. ...
    (microsoft.public.platformsdk.security)
  • Re: Using CryptoAPI to do a DH key exchange with OpenSSL
    ... So I figured out the format. ... And the first 16 bytes is header info. ... to cryptoapi obviously doesn't include the blob header info. So I ... the DH public key format in CAPI. ...
    (microsoft.public.platformsdk.security)
  • .NET to CryptoAPI questions
    ... I'm trying to encrypt and sign data in a .NET app, ... CryptoAPI for the other side. ... public key to an xml file, and transfer that file to the .NET app's ... does anyone have any ideas why the signature verification and ...
    (microsoft.public.platformsdk.security)
  • .net and CryptoAPI key information
    ... The following information may be useful to those with some CryptoAPI ... generates new RSA public/private transient key-pair each time invoked. ... constructor, a random key container name, prepended with "CLR" is persisted to ... The term "public key blob" is used a bit loosely in docs. ...
    (microsoft.public.dotnet.security)

Quantcast