コンプライアンス上の理由 (256 ビット AES と一時キーを使用したい) により、.Net で暗号スイートを再注文/削除しようとしています。ただし、WCF TCP トランスポート セキュリティを使用して、セキュリティのすべての制御を Windows の TLS 実装と優先暗号に委譲します。システムレベルの暗号を変更したくありません。
BCryptEnumContextFunctions、BCryptAddContextFunction、BCryptRemoveContextFunctionを使用してアプリケーションレベルでそれを行う方法をリストしたこの素晴らしい Microsoft ページを見つけましたが、それはすべて C であり、どこから始めればよいかを知るのに十分な P/Invoke の経験がありません。私はグーグルで検索しましたが、それをやっている人は見つかりませんでした。
MSDN ページの C++ コード スニペットを以下に示します。これらを .Net P/Invoke 呼び出しに変換するには、助けが必要です。
BCryptEnumContextFunctions
#include <stdio.h>
#include <windows.h>
#include <bcrypt.h>
void main()
{
HRESULT Status = ERROR_SUCCESS;
DWORD cbBuffer = 0;
PCRYPT_CONTEXT_FUNCTIONS pBuffer = NULL;
Status = BCryptEnumContextFunctions(
CRYPT_LOCAL,
L"SSL",
NCRYPT_SCHANNEL_INTERFACE,
&cbBuffer,
&pBuffer);
if(FAILED(Status))
{
printf_s("\n**** Error 0x%x returned by BCryptEnumContextFunctions\n", Status);
goto Cleanup;
}
if(pBuffer == NULL)
{
printf_s("\n**** Error pBuffer returned from BCryptEnumContextFunctions is null");
goto Cleanup;
}
printf_s("\n\n Listing Cipher Suites ");
for(UINT index = 0; index < pBuffer->cFunctions; ++index)
{
printf_s("\n%S", pBuffer->rgpszFunctions[index]);
}
Cleanup:
if (pBuffer != NULL)
{
BCryptFreeBuffer(pBuffer);
}
}
BCryptAddContext関数
#include <stdio.h>
#include <windows.h>
#include <bcrypt.h>
void main()
{
SECURITY_STATUS Status = ERROR_SUCCESS;
LPWSTR wszCipher = (L"RSA_EXPORT1024_DES_CBC_SHA");
Status = BCryptAddContextFunction(
CRYPT_LOCAL,
L"SSL",
NCRYPT_SCHANNEL_INTERFACE,
wszCipher,
CRYPT_PRIORITY_TOP);
}
BCryptRemoveContext関数
#include <stdio.h>
#include <windows.h>
#include <bcrypt.h>
void main()
{
SECURITY_STATUS Status = ERROR_SUCCESS;
LPWSTR wszCipher = (L"TLS_RSA_WITH_RC4_128_SHA");
Status = BCryptRemoveContextFunction(
CRYPT_LOCAL,
L"SSL",
NCRYPT_SCHANNEL_INTERFACE,
wszCipher);
}
これらを .Net に変換して、マネージ コードから呼び出して暗号を調整できるようにする方法を教えてください。ありがとう!
編集:
昨夜遅く、テストプログラムで次のことを試しました(P/Invokeで何をしているのかまだわかりません):
// I found this in bcrypt.h
const uint CRYPT_LOCAL = 0x00000001;
// I can't find this anywhere in Microsoft's headers in my SDK,
// but I found some random .c file with it in there. No idea
// what this constant actually is according to Microsoft
const uint NCRYPT_SCHANNEL_INTERFACE = 0x00010002;
public static void DoStuff()
{
PCRYPT_CONTEXT_FUNCTIONS pBuffer = new PCRYPT_CONTEXT_FUNCTIONS();
pBuffer.rgpszFunctions = String.Empty.PadRight(1500);
uint cbBuffer = (uint)Marshal.SizeOf(typeof(PCRYPT_CONTEXT_FUNCTIONS));
uint Status = BCryptEnumContextFunctions(
CRYPT_LOCAL,
"SSL",
NCRYPT_SCHANNEL_INTERFACE,
ref cbBuffer,
ref pBuffer);
Console.WriteLine(Status);
Console.WriteLine(pBuffer);
Console.WriteLine(cbBuffer);
Console.WriteLine(pBuffer.cFunctions);
Console.WriteLine(pBuffer.rgpszFunctions);
}
/*
typedef struct _CRYPT_CONTEXT_FUNCTIONS {
ULONG cFunctions;
PWSTR rgpszFunctions;
} CRYPT_CONTEXT_FUNCTIONS, *PCRYPT_CONTEXT_FUNCTIONS;
*/
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct PCRYPT_CONTEXT_FUNCTIONS
{
public uint cFunctions;
public string rgpszFunctions;
}
/*
NTSTATUS WINAPI BCryptEnumContextFunctions(
ULONG dwTable,
LPCWSTR pszContext,
ULONG dwInterface,
ULONG *pcbBuffer,
PCRYPT_CONTEXT_FUNCTIONS *ppBuffer
);
*/
[DllImport("Bcrypt.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern uint BCryptEnumContextFunctions(uint dwTable, string pszContext, uint dwInterface, ref uint pcbBuffer, ref PCRYPT_CONTEXT_FUNCTIONS ppBuffer);
私がこれまでに得た唯一の方法の現在の出力は次のとおりです。
0
MyClass+PCRYPT_CONTEXT_FUNCTIONS
2400
8934576
[1500 spaces that I initialized rgpszFunctions with, not the cipher functions]