I'm trying to P/Invoke into CryptImportKey from C# to set a known key before encrypting data that will be decrypted in a C++ Win32 service at some point. I have the method signature for the P/Invoke and that all works fine but i can't get it to accept my key blob. The C++ structs are in comments below and my C# ones for marshaling are underneath.
// typedef struct _PUBLICKEYSTRUC
// {
// BYTE bType;
// BYTE bVersion;
// WORD reserved;
// ALG_ID aiKeyAlg;
// } BLOBHEADER, PUBLICKEYSTRUC;
[StructLayout(LayoutKind.Sequential)]
public struct PUBLICKEYSTRUC
{
public Byte bType;
public Byte bVersion;
public Int16 reserved;
public Int32 aiKeyAlg;
}
//typedef struct __KEYBLOB
//{
// BLOBHEADER hdr;
// DWORD cbKeySize;
// BYTE* rgbKeyData;
//} KEYBLOB;
[StructLayout(LayoutKind.Sequential)]
public struct KEYBLOB
{
public PUBLICKEYSTRUC hdr;
public Int16 cbKeySize;
public Byte[] rgbKeyData;
}
I then use:
int len = (Marshal.SizeOf(typeof(PUBLICKEYSTRUC) + Marshal.SizeOf(typeof(KEYBLOB)) + KeySize;
byte[] arr = new byte[len];
IntPtr ptr = Marshal.AllocHGlobal(len);
Marshal.StructureToPtr(keyBlob, ptr, true);
Marshal.Copy(ptr, arr, 0,len);
Marshal.FreeHGlobal(ptr);
To get in to a byte array to pass to CryptImportKey but it never seems to take the key with it and when I encrypt with it I get different cipher text time suggesting it's not using my key.
Any ideas would be great!
EDIT:
The key blob stuff is from the C++ code I have that can successfully encrypt and decrypt the data. I think you maybe have a point about the header being included twice but the main problem I have is the value of the Byte[] rgbKeyData is not being put in to the byte array arr.