delphi OpenSSL SSL_CTX_NEW返回“传递了空的ssl方法”

ax6ht2ek  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(329)

代码:TIdSSLIOHandlerSocketOpenSSL( ASMTP.IOHandler ).SSLOptions.SSLVersions := [sslvSSLv2,sslvSSLv23,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2]
看起来问题出在方法TidSSLOptions.SetSSLVersions中,如果您设置了除单个版本之外的任何内容,它将设置fMethod := sslvSSLv23。如果不可用,TidSSLContext.SetSSLMethod将返回nil,您将得到此错误。
Indy 2015年12月,TIdSSLContext.SetSSLMethod可以返回nil。解决方案已恢复。

svdrlsy4

svdrlsy41#

有什么问题吗?没有,希望有人觉得这个有用。
这是一个问答网站。可以分享知识,但必须采用问答格式。请参阅Can I answer my own question?
在任何情况下,这听起来更像是一个错误报告,应该报告给Indy's issue tracker,而不是一个公共论坛。
也就是说,您根本不应该启用SSLv 2或SSLv 3协议,因为它们不再安全,甚至在许多OpenSSL发行版中不再可用。SSLv 23只是一个通配符,它只用于Method属性,而不是SSLVersions属性(事实上,如果您尝试使用任何其他版本指定它,它将被忽略)。您应该只在SSLVersions中使用TLSv 1+协议,让Indy根据需要在内部处理SSLv 23。

TIdSSLIOHandlerSocketOpenSSL( ASMTP.IOHandler ).SSLOptions.SSLVersions := [sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2]

看起来问题出在方法TIdSSLOptions.SetSSLVersions中,如果你设置了除单个版本之外的任何内容,它会设置fMethod:= sslvSSLv 23。
这是理所当然的,因为SSLv 23方法是OpenSSL在SSL/TLS握手过程中实现动态版本协商的方式,允许客户端和服务器协商它们都支持的最高TLS版本。否则,如果客户端只使用特定版本,而服务器不支持该版本,TLS握手将失败。
如果不可用,TidSSLContext.SetSSLMethod将返回nil,并出现此错误。
首先,SetSSLMethod()永远不会将nil返回到SSL_CTX_new()。如果OpenSSL不支持所请求的方法,SetSSLMethod()会引发EIdOSSLGetMethodError异常。
第二,这种情况意味着你不能进行版本协商,所以你必须使用特定的TLS版本来代替。这个例外是设计好的,让你知道你要求协商,但是你的OpenSSL版本不支持它,所以尝试其他的方法。
最简单的解决方法是在设置SSL版本后设置方法
MethodSSLVersions属性是互斥的,设定其中一个会更新另一个。但是,Method已过时,您应该只使用SSLVersions,即使是单一TLS版本。
这可能也不存在,所以更好的解决方案可能是在indy:
您的解决方法在请求SSLv 23时完全禁用版本协商。这不是Indy实现的可行选项。
真实的的解决方案是当SSLv 23不可用时,您自己的代码捕获EIdOSSLGetMethodError异常,然后您可以根据需要使用单个TLS版本重新尝试连接。

相关问题