TLS 1.2 - 函数提供的令牌无效

3
我有一个奇怪的问题,SslStream.AuthenticateAsClient() 抛出以下异常:
System.Security.Authentication.AuthenticationException : A call to SSPI failed, see inner exception.
  ----> System.ComponentModel.Win32Exception : The token supplied to the function is invalid

只有当客户端需要Tls12时才会发生这种情况:
SslStream.AuthenticateAsClient(..., ..., SslProtocols.Tls12);

对于 Ssl3、Tls11 和 Tls,代码可以正常工作。

服务器证书是自签名的且“旧”。它使用 md5RSA 签名和 1024 位密钥。最初我认为这是问题所在,因为重新生成证书会使异常消失(我尝试了 SHA1 和 SHA512 - 都没有问题)。

然而,令我惊讶的是,FileZilla 客户端能够使用这个“旧”的 md5RSA 签名证书并使用 TLS 1.2 连接到该服务器:

TLS 1.2 with old cert

以下是该证书:

-----BEGIN CERTIFICATE-----
MIICejCCAeOgAwIBAgIQzbvZdHHAV49D7R8OE2mEaDANBgkqhkiG9w0BAQQFADBA
MSswKQYJKoZIhvcNAQkBFhxlbWFpbEBpbi10aGUtY2VydGlmaWNhdGUuY29tMREw
DwYDVQQDEwhKb2huIERvZTAeFw0xMTAxMjAyMDAzNDFaFw0zOTEyMzEyMzU5NTla
MEAxKzApBgkqhkiG9w0BCQEWHGVtYWlsQGluLXRoZS1jZXJ0aWZpY2F0ZS5jb20x
ETAPBgNVBAMTCEpvaG4gRG9lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0
s5RAKYdw2AYk3t0oH5jDo6RQRRfabkOLfKvR8kOiYbqjtgblx7JhSZJHX/r6KLoc
hGgYkQPOSKnl8TdgEkzPxWHECV/iMdOxTsTv2P//ZM2INjb4H8JjDS16PYFwHP3w
/9RU6PjppK+mPdWP1pezBzebSM0QQwpmXlSmfe2ULQIDAQABo3UwczBxBgNVHQEE
ajBogBA4WNgTvhkmRD8DhHeRvAJcoUIwQDErMCkGCSqGSIb3DQEJARYcZW1haWxA
aW4tdGhlLWNlcnRpZmljYXRlLmNvbTERMA8GA1UEAxMISm9obiBEb2WCEM272XRx
wFePQ+0fDhNphGgwDQYJKoZIhvcNAQEEBQADgYEAFX6MM/E97hC6t1TAFBmM3tWr
fQ2cB0LFCe6J0I8phKQecpSYCkMdvaHdsT+sdzXNW4bgL064r731r8l/47VgfgIR
oRmsQYnwJ55nqZpEW2zL3vioedWiCVto8X9/dVC8jqPpcmMP5NWBHh88o7nkPBxe
C8iucrQvHnjYwaz1o/M=
-----END CERTIFICATE-----

我的问题是:

  1. 为什么SslStream.AuthenticateAsClient会抛出异常,而Filezilla客户端却能连接?

  2. 在使用TLS 1.2时,是否存在任何.NET/Windows 10/CryptoAPI证书限制?

  3. 如果存在限制,为什么FileZilla没有强制执行它们?

  4. 为什么错误信息如此晦涩:“提供给函数的令牌无效”?


检查证书是否只能用于加密并禁止签名生成。您可以在Windows或其他证书查看器中查看它,搜索"key usage"。对于ECDHE和DHE密码套件,您需要进行身份验证(签名生成)。 - undefined
@MaartenBodewes 我在任何地方都没有看到“键使用”(certmgr/Open/Details/All)。该证书是使用 makecert.exe 和“-sky exchange”选项创建的(该选项表示密钥用于密钥加密和密钥交换),正如我之前说的,FileZilla客户端对该服务器证书没有任何问题。我将更新问题并附上证书本身。 - undefined
@MaartenBodewes:我遇到了同样的问题,并且可以确认控制变量是TLS 1.2;如果我强制降级到TLS 1.0,它就能通过;显然,我实际上并不想这样做。 - undefined
2个回答

10

我终于弄明白了。在这种情况下,“The token supplied to the function is invalid”意味着“证书链上的证书使用了不受支持或已禁用的算法。”

实际上,这几乎总是指已禁用。启用的算法列表可以在 HKEY_LOCAL_MACHINE SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010003 Functions中找到。这是一个REG_MULTI_SZ,每个支持的算法都有一个字符串。

我在我的Windows 10机器上找到了以下值:

RSA/SHA256
RSA/SHA384
RSA/SHA1
ECDSA/SHA256
ECDSA/SHA384
ECDSA/SHA1
DSA/SHA1

我已经添加了。
RSA/SHA512
ECDSA/SHA512

如果您添加了RSA/MD5,则您的密钥将开始工作,但是不能强调这是一个不好的想法,并且会使您的系统接受伪造证书,因为MD5已被攻破。

Filezilla可以工作,因为Mozilla不信任主机密码套件。


这也有助于MS SQL 2017服务器。 SQL 2017已配置为强制加密,使用自签名证书。我的Win 10电脑可以连接SSMS,但是两位同事遇到了以下错误: “与服务器成功建立了连接,但在登录过程中发生错误。(提供程序:SSL提供程序,错误:0 - 提供给函数的令牌无效)(Microsoft SQL Server,错误:-2146893048)” 在我找到这篇文章之前,经历了很多更新和失败的搜索。将相同的两个算法添加到注册表并重新启动电脑后,问题得到解决。谢谢! - undefined
如果您使用Netsh捕获ETL跟踪,并在NetworkMonitor中查看,您还会看到以下内容:WEBIO_MicrosoftWindowsWebIO WEBIO_MicrosoftWindowsWebIO:0x07E5D820: InitializeSecurityContext返回-(未知值:1) 错误值将为SEC_E_INVALID_TOKEN,并且如果您正在使用WinHTTP,则在跟踪的WinHTTP级别上稍后也会出现以下内容: WEBIO_MicrosoftWindowsWebIO WEBIO_MicrosoftWindowsWebIO:0x07E58A28: 完成WebSendHttpRequest(Entity)(DataChunks 0x036D6FC4)(错误SEC_E_INVALID_TOKEN)(CompletionContext 0x07E58878)(CompletionInformation 0(0x0)) - undefined

0
升级curl到最新版本8.4.0解决了我的问题。这里是如何做的how
另外,由于上述链接中提到的原因,你可能也希望尽快升级curl到8.4.0版本:
引用: 2023年10月3日,curl团队预先公布了一个正在处理中的修复方案,该方案解决了一个影响libcurl和curl的高危漏洞。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接