==============================
Some Notes On The CngRsa Class
==============================

System Requirements
===================

  The Cryptography API, Next Generation (CNG) is only
  available in Windows Vista or later.


Adding CngRsa.cls To Projects
=============================

The class is self-contained, and doesn't have any dependencies
besides Windows Vista or later.  It doesn't require any helper
classes or static modules.


Miscellaneous
=============

  Key Containers
  --------------

  If you want to implement such a thing you may want to use
  the BCRYPT_RSAKEY_BLOB struct (or in VB: UDT) to build and
  break down the binary key BLOBs.  You may also wish to
  reverse the byte-sequence of the extracted values since
  Windows CNG uses little-endian values while the
  multiplatform standard for echange is big-endian.

  In this implemention we just deal with the raw CNG BLOBs.
  This works fine if everyone involved is using Windows,
  but in multiplatform scenarios it won't be adequate.


  BCryptGenRandom
  ---------------

  You could easily modify CngRsa.cls to use BCryptGenRandom
  instead of the technique actually used here for creating
  random values in CreateRandom and CreateSecret.

  See the comments in the code, but also note that doing
  this will require that you open:

    o BCRYPT_RNG_ALGORITHM
      or
    o BCRYPT_RNG_FIPS186_DSA_ALGORITHM


  Encrypted Payloads or "Messages"
  --------------------------------

  After encrypting you must package up several values in
  some manner to make up the "message" to store or send:

    o The encrypted secret, generated via a call to
      CreateSecret.

    o The initialization vector, generated via a call to
      Encrypt and retrieved via the IV property.

    o The specifics required due to any "salt" you might
      use, i.e. any data the decrypter might need to know
      (length?) to deal with it.

    o The actual length of the original plain text, so that
      following decryption any padding can be truncated.
      This is often inserted as a prefix to the plain text
      before encrypting.

  If the information you are encrypting is insenstive to any
  padding you don't need to worry about passing the original
  length along.

  If you don't use any salt scheme, or a simple fixed-length
  prefix, suffix, etc. then you don't need to pass any
  information about your salt either.


  CloseKey Method
  ---------------

  CloseKey is called when an instance of CngRsa is released.
  Calling this method is always safe even if the class
  instance has not been used.

  The "open" action occurs when properties PrivateKey or
  PublicKey are assigned a value.


Calling Sequences
=================

  How To Create A Key Pair
  ------------------------

    o Call CreateRsaKeyPair passing two Byte arrays (PrivateKey
      and PublicKey).  Does not set the properties with the same
      names!

    o Save both BLOBs to disk, after encrypting them separately
      some other way if desired to protect these keys.  Give the
      PublicKey to those who need to send you secure messages.
      Keep and use the PrivateKey yourself to decrypt such
      messages.


  How To Encrypt
  --------------

  Set the key:

    o Obtain key BLOB from disk, decrypting it if stored on disk
      in encrypted form.

    o Assign key BLOB to PublicKey or PrivateKey as appropriate.

  For each message to be encrypted:

    o Call CreateSecret, or assign EncryptedSecret if reusing a
      saved secret.

    o Get plain text to be encrypted.  Apply compression if
      desired (deflate, gzip, etc.), add salt if desired.  This
      CngRsa class does not do any compression or decompression
      of the encryted data.

    o Note length of (possibly compressed) plain text.  This is
      needed after decryption due to block padding, so consider
      adding it to the plain text as a prefixed value or else
      keep it out of band as a separate value.

    o Call Encrypt passing two Byte arrays (Bytes and
      EncryptedBytes).  This generates a new IV value available
      via he IV property after this call completes.

    o Store or transmit EncryptedSecret, IV, plain text length (if
      not in-band), and EncryptedBytes. These four values are what
      make up the complete "encrypted message." 

  Finish:

    o Call CloseKey when no more messages to encrypt.  Releases
      crypto handles and secret storage.


  How To Decrypt
  --------------

  Set the key:

    o Obtain key BLOB from disk, decrypting it if stored on disk
      in encrypted form.

    o Assign key BLOB to PublicKey or PrivateKey as appropriate.

  For each message to be encrypted:

    o Get encrypted secret BLOB, assign to EncryptedSecret.

    o Get initialization vector BLOB, assign to IV.

    o Get encrypted cipher text BLOB to be decrypted.

    o Call Decrypt passing two Byte arrays (EncryptedBytes and
      Bytes).

    o Obtain plain text length, extracting it if part of the
      body.  Then extract decrypted plain text portion based on
      this actual length, removing salt if any, then apply
      decompression if necessary.

    o Use plain text result.

  Finish:

    o Call CloseKey when you have no more messages to decrypt
      using the current key.  This releases crypto handles and
      secret storage.


Class Member Calling Sequence Dependencies
==========================================

  CloseRsa requires:

    *nothing*


  CreateRsaKeyPair requires

    *nothing*


  CreateSalt requires:

    *nothing*


  CreateSecret requires:

    o PrivateKey (Let) or PublicKey (Let)


  Decrypt requires:

    o EncryptedSecret (Let)

    o IV (Let)


  Encrypt requires:

    o CreateSecret or EncryptedSecret (Let)


  EncryptedSecret (Get) requires:

    o CreateSecret or EncryptedSecret (Let)


  EncryptedSecret (Let) requires:

    o PrivateKey (Let) or PublicKey (Let)


  IV (Get) requires:

    o Encrypt or IV (Let)


  IV (Let) requires:

    *nothing*


  PrivateKey (Let) requires:

    *nothing*


  PublicKey (Let) requires:

    *nothing*
