It's not my answer, just found a good explanation on the Internet:
AT_SIGNATURE key acn ONLY be used to sign a message. It cannot be used to
wrap (export) session key. AT_KEYEXCHANGE key can be used for BOTH purposes.
So if you want to use only 1 (one) key pair for both, you definitely need
AT_KEYEXCHANGE key pair.
You also need to understand some security implications - and why using two
keys are better than using the same key pair for both:
Normally you should NEVER reveal your signing private key. If it is lost, you
simply generate a new signing key pair and use that from that point of time.
On the other hand, you normally need to back up your key exchange key,
because without that you cannot decrypt messages in the future (if the
private key is lost). However, backup means that the key may be available to
someone else - who now could sign messages purportedly coming from you - and
you wouldn't want that.
If you use different key pairs for the two actions you can have secure
signing (your signing private key never goes out) and still can back up your
key exchange key.
One more note on generating these keys:
Since you don't want your signing key know, when you generate it with
CryptGenKey(AT_SIGNATURE) you should never set flags KEY_EXPORTABLE or
KEY_ARCHIVABLE and you may want the extra protection and add
CRYPT_USER_PROTECTED, so every time the signing key is used the user knows it.
On the other hand, when generating the key exchange key using
CryptGenKey(AT_KEYEXCHANGE) you should immediately back it up: set the flag
CRYPT_ARCHIVABLE and IMMEDIATELY export the key for backup. (This flag allows
to export the key only once - right after it is created -, so it is more
secure than allowing to be exported any time by setting CRYPT_EXPORTABLE.)
Laszlo Elteto
SafeNet, Inc.