【发布时间】:2013-10-30 23:15:49
【问题描述】:
由于合规性原因(我想在 .Net 中使用 256 位 AES 和临时密钥),我正在尝试重新排序/删除密码套件。但是,使用 WCF TCP 传输安全性,我将所有对安全性的控制权交给了 Windows 的 TLS 实现及其首选密码。我不想更改系统级密码。
我发现这个great Microsoft page 列出了如何使用BCryptEnumContextFunctions、BCryptAddContextFunction、BCryptRemoveContextFunction 在应用程序级别执行此操作,但这全是 C,我什至没有足够的 P/Invoke 经验知道从哪里开始。我用谷歌搜索,但没有发现有人这样做。
MSDN 页面上的 C++ 代码 sn-ps 如下,我需要帮助将它们转换为 .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);
}
}
BCryptAddContextFunction
#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);
}
BCryptRemoveContextFunction
#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]
【问题讨论】:
-
您能展示一下到目前为止您尝试过的内容吗?
-
@DavidHeffernan 除了我从 PInvoke.net 复制的内容之外,我对 P/Invoke 真的不太了解,但也就是说,我昨晚确实尝试过,我添加到质疑我对检索功能的尝试。不用说,它不起作用。
标签: c# .net ssl pinvoke schannel