Re: .NET CryptoAPITransform and KeyHandle interop
From: Michel Gallant (neutron_at_NOSPAMistar.ca)
Date: 12/31/03
- Previous message: John Banes [MS]: "Re: Thread safety"
- In reply to: Ivan Medvedev [MS]: "Re: .NET CryptoAPITransform and KeyHandle interop"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Date: Tue, 30 Dec 2003 20:43:28 -0500
Thanks Ivan.
To clarify again, I am trying simply to Pinvoke in order to export
a SIMPLEBLOB (not PLAINTEXTBLOB with ExponentOf1 approach).
SIMPLEBLOB is supported in W2k, and I do want to export the symmetric
key as encrypted (not as cleartext which is what ExpOf1 is for).
I can get CryptExportKey to output a SIMPLEBLOB in C, and also if
I use only Pinvoke alone in the code (see sample snippet added below).
The code below shows what works (full Pinvoke) and what doesn't work.
If the symmetric key is generated via Pinvoke directly, then there is no
problem Pinvoking CryptExportKey( .... SIMPLEBLOB ...) and getting
the expected SIMPLEBLOB structure blob.
However, if the symmetric key is obtained via CryptoAPITransform.KeyHandle
(which is an IntPtr representing a handle to native symmetric key), then CryptExportKey
(with same exchange key handle) fails.
- Mitch
-----------
IntPtr hProv = IntPtr.Zero;
IntPtr hXchgKey = IntPtr.Zero;
IntPtr hsymKey = IntPtr.Zero;
uint blobbytes = 0;
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
ICryptoTransform encryptor = tdes.CreateEncryptor() ; //used random-generated key/IV values
CryptoAPITransform capitrans = (CryptoAPITransform) encryptor ;
//---- Method 1: Get symmetric key handle via .NET property ------------
hsymkey = capitrans.KeyHandle ; //native key handle
//----- Method 2: Get symmetric key handle via Pinvoke ----------------
//if(Win32.CryptGenKey(hProv, CALG_3DES, CRYPT_EXPORTABLE, ref hsymKey))
// Console.WriteLine("Got random 3DES key") ;
//else
// showWin32Error(Marshal.GetLastWin32Error());
if (!Win32.CryptAcquireContext(ref hProv, "mycontainer", MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
return;
if(Win32.CryptGetUserKey(hProv, AT_KEYEXCHANGE, ref hXchgKey)) //OK; no problems
{
Console.WriteLine("Successfully got container exchange key {0}",hXchgKey) ;
//--- Method 1 fails; Method 2 works -----
if(Win32.CryptExportKey(hsymkey, hXchgKey, SIMPLEBLOB, 0, null, ref blobbytes))
Console.WriteLine("Got simpleblob bytes {0}", blobbytes) ;
else
showWin32Error(Marshal.GetLastWin32Error());
------------------
"Ivan Medvedev [MS]" <ivanmed@online.microsoft.com> wrote in message
news:eQePvUwzDHA.1500@TK2MSFTNGP12.phx.gbl...
> Michel -
> off the top of my head I can not explain what you are observing. We are
> using CRYPT_EXPORTABLE pretty much everywhere, so the key handles should be
> consumable (in the same process at least). When working with symmetrics
> algorithms we are using the exponent-of-1 technique to import the session
> key, so if you wanted to get it back you would need to use the same process
> (there is a KB article in MSDN on importing plain session keys that way).
> --Ivan
> http://blogs.dotnetthis.com/ivan
> http://www.dotnetthis.com
> This posting is provided "AS IS" with no warranties, and confers no rights.
>
>
> "Michel Gallant" <neutron@NOSPAMistar.ca> wrote in message
> news:eSAI1YnxDHA.2520@TK2MSFTNGP10.phx.gbl...
> > If one invokes CryptGetKeyParam() on CryptoAPITransform.KeyHandle
> > with KP_PERMISSIONS, the result DOES indicate that the key is exportable.
> > Also, all other parameters returned by this function are exactly what one
> expects
> > for the .NET provider with default constructor
> TripleDESCryptoServiceProvider().
> >
> > However, when that KeyHandle is passed to CryptExportKey() via Pinvoke,
> > with SIMPLEBLOB, the result fails as below with Bad Key 0x80004005.
> > The exchange key is successfully obtained with no problem via:
> > Win32.CryptAcquireContext(ref hProv, null, MS_ENHANCED_PROV,
> PROV_RSA_FULL, 0)
> > Win32.CryptGetUserKey(hProv, AT_KEYEXCHANGE, ref hXchgKey)
> >
> > Is there a potential problem because there are actually 2 instances of CSP
> involved,
> > one via .NET and one via CryptAcquireContext ??
> >
> > If I use CryptGenKey() (instead of using CryptoAPITransform.KeyHandle) to
> get
> > a symmetric key, the handle returned *can* be successfully exported with
> CryptExportKey().
> >
> > Any ideas?
> > - Mitch
> >
> > "Ivan Medvedev [MS]" <ivanmed@online.microsoft.com> wrote in message
> > news:OEAPBOexDHA.3224@tk2msftngp13.phx.gbl...
> > > Michel -
> > > it depends on the version. In Whidbey (tech preview was made available
> at
> > > the PDC) this will be specified with CspProviderFlags.
> > > --Ivan
> > > http://blogs.dotnetthis.com/ivan
> > >
> > > "Michel Gallant" <neutron@NOSPAMistar.ca> wrote in message
> > > news:OX0YyZXxDHA.3220@tk2msftngp13.phx.gbl...
> > > > I understand that CryptoAPITransform.KeyHandle returns a
> > > > handle to the native symmetric key handle (for underlying capi
> > > > CSP like RC2, TripleDES etc..)
> > > >
> > > > There is no problem acquiring such a keyhandle in managed code:
> > > >
> > > > CryptoAPITransform capitrans = (CryptoAPITransform) encryptor ;
> > > > IntPtr hsymkey = capitrans.KeyHandle ; //native key handle
> > > >
> > > > but this keyhandle fails when supplied to CryptoAPI functions via
> Pinvoke
> > > > (typically with Bad Key error).
> > > > Anyone with experience here?
> > > >
> > > > Is the underlying SymmetricAlgorithm keyhandle marked as "Exportable"
> in
> > > > capi? SymmetricAlgorithm classes don't seem to have properties that
> allow
> > > > controlling some dwFlags that CryptoGenKey() does.
> > > >
> > > > Thanks,
> > > > - Mitch Gallant
> > > > MVP Security
> > > >
> > > >
> > >
> > >
> >
> >
>
>
- Previous message: John Banes [MS]: "Re: Thread safety"
- In reply to: Ivan Medvedev [MS]: "Re: .NET CryptoAPITransform and KeyHandle interop"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|