SChannel,SEC_E_ALGORITHM_MISMATCH (0x80090331)
SChannel, SEC_E_ALGORITHM_MISMATCH (0x80090331)
几天的故障排除、谷歌搜索解决方案和重新阅读有关所需功能的 Microsoft 文档。改变变量,一次又一次地重试。非常感谢您的帮助,我相信不仅仅是我 运行 参与其中。
我正在努力实现联网的客户端和服务器应用程序,这些应用程序使用 SChannel 与 SSL/TLS 层进行通信(稍后还将使用 OpenSSL 实现交叉兼容性)。我有一个已知可以工作的客户端,所以我们可以专注于服务器端。
目前的目标是让它在不提供任何一方证书的情况下工作(它们应该根据需要即时生成)。我执行 AcquireCredentialsHandle,从客户端(同一主机上的 运行)加载初始令牌并调用 AcceptSecurityContext。
似乎无论我更改什么变量,我在第一次调用 AcceptSecurityContext 时总是以相同的 0x80090331 错误结束。在 windows 7 & Windows Server 2012 上测试。
在我看来,我的代码之外肯定有一些东西,我需要修复的 OS 设置。我在网上发现相互矛盾的信息。 TLS 1.1 和 TLS 1.2 已添加到 SecurityProviders\SCHANNEL\Protocols* 下的注册表中,并设置了数据 DisabledByDefault=0。还在 'SecurityProviders'.
中添加了“, schannel.dll”
代码如下:
... snip ...(调用 AcquireCredentialsHandle 的代码)
PCCERT_CONTEXT serverCerts[1] = {0};
SCHANNEL_CRED sc = {0};
sc.dwVersion = SCHANNEL_CRED_VERSION;
//sc.grbitEnabledProtocols = SP_PROT_SSL3_SERVER | SP_PROT_TLS1_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_2_SERVER;
sc.grbitEnabledProtocols = SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_2_SERVER;
sc.dwFlags = 0;
sc.cCreds = 0; // Let Crypto API find the appropriate certificate for us
sc.paCred = serverCerts;
TimeStamp tsExpiry;
SECURITY_STATUS status = AcquireCredentialsHandle(
NULL,
UNISP_NAME,
SECPKG_CRED_INBOUND,
NULL,
&sc,
NULL,
NULL,
&hCredential,
&tsExpiry);
std::cout << "AcquireCredentialsHandle result = 0x" << std::hex << status << std::endl;
...剪断...(调用 AcceptSecurityContext 的代码)
// TOKEN is received from client into m_receivedData
//std::vector<char> m_receivedData;
m_ctxtFlags = ASC_REQ_ALLOCATE_MEMORY | ASC_REQ_STREAM;
SecBuffer inBuffers[2];
// Provide Schannel with the remote host's handshake data
inBuffers[0].pvBuffer = (char*)(&m_receivedData[0]);
inBuffers[0].cbBuffer = (unsigned long)m_receivedData.size();
inBuffers[0].BufferType = SECBUFFER_TOKEN;
inBuffers[1].pvBuffer = NULL;
inBuffers[1].cbBuffer = 0;
inBuffers[1].BufferType = SECBUFFER_EMPTY;
SecBufferDesc inBufferDesc = {0};
inBufferDesc.cBuffers = 2;
inBufferDesc.pBuffers = inBuffers;
inBufferDesc.ulVersion = SECBUFFER_VERSION;
SecBuffer outBuffers[2];
// We let Schannel allocate the output buffer for us
outBuffers[0].pvBuffer = NULL;
outBuffers[0].cbBuffer = 0;
outBuffers[0].BufferType = SECBUFFER_TOKEN;
// Contains alert data if an alert is generated
outBuffers[1].pvBuffer = NULL;
outBuffers[1].cbBuffer = 0;
outBuffers[1].BufferType = SECBUFFER_ALERT;
SecBufferDesc outBufferDesc = {0};
outBufferDesc.cBuffers = 2;
outBufferDesc.pBuffers = outBuffers;
outBufferDesc.ulVersion = SECBUFFER_VERSION;
unsigned long fContextAttr;
TimeStamp tsTimeStamp;
SECURITY_STATUS status = NULL;
if (isFirstCall) {
status = AcceptSecurityContext(
&hCredential,
NULL,
&inBufferDesc,
m_ctxtFlags,
0,
&hNewContext,
&outBufferDesc,
&fContextAttr,
NULL);
std::cout << "AcceptSecurityContext (isFirstCall) result = 0x" << std::hex << status << std::endl;
}
SSL/TLS 需要服务器端证书。缺少服务器端证书会生成 0x80090331 错误。下一步是根据需要创建自签名证书。参见 CertCreateSelfSignCertificate. A C example using CryptoAPI can be found here。
几天的故障排除、谷歌搜索解决方案和重新阅读有关所需功能的 Microsoft 文档。改变变量,一次又一次地重试。非常感谢您的帮助,我相信不仅仅是我 运行 参与其中。
我正在努力实现联网的客户端和服务器应用程序,这些应用程序使用 SChannel 与 SSL/TLS 层进行通信(稍后还将使用 OpenSSL 实现交叉兼容性)。我有一个已知可以工作的客户端,所以我们可以专注于服务器端。
目前的目标是让它在不提供任何一方证书的情况下工作(它们应该根据需要即时生成)。我执行 AcquireCredentialsHandle,从客户端(同一主机上的 运行)加载初始令牌并调用 AcceptSecurityContext。
似乎无论我更改什么变量,我在第一次调用 AcceptSecurityContext 时总是以相同的 0x80090331 错误结束。在 windows 7 & Windows Server 2012 上测试。
在我看来,我的代码之外肯定有一些东西,我需要修复的 OS 设置。我在网上发现相互矛盾的信息。 TLS 1.1 和 TLS 1.2 已添加到 SecurityProviders\SCHANNEL\Protocols* 下的注册表中,并设置了数据 DisabledByDefault=0。还在 'SecurityProviders'.
中添加了“, schannel.dll”代码如下:
... snip ...(调用 AcquireCredentialsHandle 的代码)
PCCERT_CONTEXT serverCerts[1] = {0};
SCHANNEL_CRED sc = {0};
sc.dwVersion = SCHANNEL_CRED_VERSION;
//sc.grbitEnabledProtocols = SP_PROT_SSL3_SERVER | SP_PROT_TLS1_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_2_SERVER;
sc.grbitEnabledProtocols = SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_2_SERVER;
sc.dwFlags = 0;
sc.cCreds = 0; // Let Crypto API find the appropriate certificate for us
sc.paCred = serverCerts;
TimeStamp tsExpiry;
SECURITY_STATUS status = AcquireCredentialsHandle(
NULL,
UNISP_NAME,
SECPKG_CRED_INBOUND,
NULL,
&sc,
NULL,
NULL,
&hCredential,
&tsExpiry);
std::cout << "AcquireCredentialsHandle result = 0x" << std::hex << status << std::endl;
...剪断...(调用 AcceptSecurityContext 的代码)
// TOKEN is received from client into m_receivedData
//std::vector<char> m_receivedData;
m_ctxtFlags = ASC_REQ_ALLOCATE_MEMORY | ASC_REQ_STREAM;
SecBuffer inBuffers[2];
// Provide Schannel with the remote host's handshake data
inBuffers[0].pvBuffer = (char*)(&m_receivedData[0]);
inBuffers[0].cbBuffer = (unsigned long)m_receivedData.size();
inBuffers[0].BufferType = SECBUFFER_TOKEN;
inBuffers[1].pvBuffer = NULL;
inBuffers[1].cbBuffer = 0;
inBuffers[1].BufferType = SECBUFFER_EMPTY;
SecBufferDesc inBufferDesc = {0};
inBufferDesc.cBuffers = 2;
inBufferDesc.pBuffers = inBuffers;
inBufferDesc.ulVersion = SECBUFFER_VERSION;
SecBuffer outBuffers[2];
// We let Schannel allocate the output buffer for us
outBuffers[0].pvBuffer = NULL;
outBuffers[0].cbBuffer = 0;
outBuffers[0].BufferType = SECBUFFER_TOKEN;
// Contains alert data if an alert is generated
outBuffers[1].pvBuffer = NULL;
outBuffers[1].cbBuffer = 0;
outBuffers[1].BufferType = SECBUFFER_ALERT;
SecBufferDesc outBufferDesc = {0};
outBufferDesc.cBuffers = 2;
outBufferDesc.pBuffers = outBuffers;
outBufferDesc.ulVersion = SECBUFFER_VERSION;
unsigned long fContextAttr;
TimeStamp tsTimeStamp;
SECURITY_STATUS status = NULL;
if (isFirstCall) {
status = AcceptSecurityContext(
&hCredential,
NULL,
&inBufferDesc,
m_ctxtFlags,
0,
&hNewContext,
&outBufferDesc,
&fContextAttr,
NULL);
std::cout << "AcceptSecurityContext (isFirstCall) result = 0x" << std::hex << status << std::endl;
}
SSL/TLS 需要服务器端证书。缺少服务器端证书会生成 0x80090331 错误。下一步是根据需要创建自签名证书。参见 CertCreateSelfSignCertificate. A C example using CryptoAPI can be found here。