private static bool kull_m_crypto_hkey_session(uint calgid, IntPtr key, uint keyLen, uint flags, IntPtr hSessionKey, IntPtr hSessionProv) { bool status = false; IntPtr keyblob, pbSessionBlob, ptr; uint dwkeyblob = 0; uint dwLen = 0; string container; IntPtr hPrivateKey; RSAPUBKEY pubk = new RSAPUBKEY(); container = Guid.NewGuid().ToString(); if (Natives.CryptAcquireContextA(ref hSessionProv, container, null, PROV_RSA_AES, CRYPT_NEWKEYSET)) { hPrivateKey = IntPtr.Zero; if (Natives.CryptGenKey(hSessionProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE | (RSA1024BIT_KEY / 2), hPrivateKey)) // 1024 { if (Natives.CryptExportKey(hPrivateKey, IntPtr.Zero, PRIVATEKEYBLOB, 0, IntPtr.Zero, ref dwkeyblob)) { keyblob = Marshal.AllocHGlobal((int)dwkeyblob); if (keyblob != IntPtr.Zero) { if (Natives.CryptExportKey(hPrivateKey, IntPtr.Zero, PRIVATEKEYBLOB, 0, keyblob, ref dwkeyblob)) { Natives.CryptDestroyKey(hPrivateKey); hPrivateKey = IntPtr.Zero; Marshal.PtrToStructure(IntPtr.Add(keyblob, Marshal.SizeOf(typeof(PUBLICKEYSTRUC))), pubk); dwLen = pubk.bitlen / 8; pubk.pubexp = 1;//NOTE ptr = IntPtr.Add(keyblob, Marshal.SizeOf(typeof(PUBLICKEYSTRUC)) + Marshal.SizeOf(typeof(RSAPUBKEY))); ptr = IntPtr.Add(ptr, 2 * (int)dwLen); // Skip pubexp, modulus, prime1, prime2 Marshal.WriteByte(ptr, 1); //*ptr = 1; // Convert exponent1 to 1 ZeroMemory(IntPtr.Add(ptr, 1), ((int)dwLen / 2) - 1); ptr = IntPtr.Add(ptr, (int)dwLen / 2); //ptr += dwLen / 2; // Skip exponent1 Marshal.WriteByte(ptr, 1); //*ptr = 1; // Convert exponent2 to 1 ZeroMemory(IntPtr.Add(ptr, 1), ((int)dwLen / 2) - 1); ptr = IntPtr.Add(ptr, (int)dwLen); //ptr += dwLen; // Skip exponent2, coefficient Marshal.WriteByte(ptr, 1); //*ptr = 1; // Convert privateExponent to 1 ZeroMemory(IntPtr.Add(ptr, 1), ((int)dwLen / 2) - 1); if (Natives.CryptImportKey(hSessionProv, keyblob, dwkeyblob, IntPtr.Zero, 0, ref hPrivateKey)) { dwkeyblob = (uint)((1024 / 2 / 8) + sizeof(uint) + Marshal.SizeOf(typeof(BLOBHEADER))); // 1024 pbSessionBlob = Marshal.AllocHGlobal((int)dwkeyblob); BLOBHEADER bSessionBlob = new BLOBHEADER(); if (pbSessionBlob != IntPtr.Zero) { bSessionBlob.bType = SIMPLEBLOB; bSessionBlob.bVersion = CUR_BLOB_VERSION; bSessionBlob.reserved = 0; bSessionBlob.aiKeyAlg = calgid; Marshal.StructureToPtr(bSessionBlob, pbSessionBlob, false); ptr = IntPtr.Add(pbSessionBlob, Marshal.SizeOf(typeof(BLOBHEADER))); Marshal.WriteInt32(ptr, CALG_RSA_KEYX); // *(ALG_ID*)ptr = CALG_RSA_KEYX; ptr = IntPtr.Add(ptr, sizeof(uint)); // ptr += sizeof(ALG_ID); for (int i = 0; i < keyLen; i++) { Marshal.WriteByte(IntPtr.Add(ptr, i), Marshal.ReadByte(IntPtr.Add(key, (int)keyLen - i - 1))); //ptr[i] = ((LPCBYTE)key)[keyLen - i - 1]; } ptr = IntPtr.Add(ptr, (int)keyLen + 1); //ptr += (keyLen + 1); for (int i = 0; i < dwkeyblob - (sizeof(uint) + Marshal.SizeOf(typeof(BLOBHEADER)) + keyLen + 3); i++) { if (Marshal.ReadByte(IntPtr.Add(ptr, i)) == 0) { Marshal.WriteByte(IntPtr.Add(ptr, i), 0x42); //ptr[i] = 0x42; } } Marshal.WriteByte(IntPtr.Add(pbSessionBlob, (int)dwkeyblob - 2), 2);//pbSessionBlob[dwkeyblob - 2] = 2; status = Natives.CryptImportKey(hSessionProv, pbSessionBlob, dwkeyblob, hPrivateKey, flags, ref hSessionKey); Marshal.FreeHGlobal(pbSessionBlob); } } } Marshal.FreeHGlobal(keyblob); } } } if (hPrivateKey != IntPtr.Zero) { Natives.CryptDestroyKey(hPrivateKey); } if (!status) { kull_m_crypto_close_hprov_delete_container(hSessionProv); } } return(status); }