我们正在尝试设置TLS1.2连接。已经在Macbook中下载了最新的OpenSSL。使用此code创建TLS1.2连接 然而,这条特定的线可能会导致这个问题。它使用TLSv1。
/* ---------------------------------------------------------- *
* Set SSLv2 client hello, also announce SSLv3 and TLSv1 *
* ---------------------------------------------------------- */
method = SSLv23_client_method();
尝试了TLSv1_2_client_method()
方法,但它给出了以下链接错误:
架构x86_64的未定义符号:" _TLSv1_2_client_method", 引自: _main in sslconnect-7aa462.o
如果有人可以帮助创建TLS1.2连接然后从目标C调用(如果对套接字编程需要一些特殊处理),那将是一个很大的帮助。
[请注意,我不是iOS用户。我正在帮助团队解决问题。虽然团队有一些经验,但我自己也是套接字编程的新手。]
答案 0 :(得分:3)
尝试了TLSv1_2_client_method()方法,但它给出了以下链接 错误:
架构x86_64的未定义符号:“_ TLSv1_2_client_method”,引自: _main in sslconnect-7aa462.o
好的,听起来你正在链接x86_64
,但你需要iOS。您可以使用以下两个命令验证体系结构:
xcrun -sdk iphoneos lipo -info libcrypto.a
xcrun -sdk iphoneos lipo -info libssl.a
例如:
$ xcrun -sdk iphoneos lipo -info /usr/local/ssl/ios/lib/libcrypto.a
Architectures in the fat file: /usr/local/ssl/ios/lib/libcrypto.a are: armv7 armv7s arm64 i386
前三个架构是自我解释的;而i386适用于iOS调试器。
注意:/usr/local/ssl/ios/
是我在构建之后安装OpenSSL for iOS的地方。 Apple没有提供它。
如果您没有四种iOS架构,那么您有两种选择。首先,您可以根据User Guide for the OpenSSL FIPS Object Module,附录E.2,第122页中的iOS程序进行构建。
其次是从GitHub下载预建版本。这是使用OpenSSL程序构建的OpenSSL 1.0.1h的noloader的GitHub。这是来自Stefan Arentz的另一个似乎非常受欢迎的,但它的OpenSSL 1.0.1g。
然后从目标C
调用
C与Objective C一起工作正常。调用它没什么特别的。
...支持iPhone应用程序的SNI
在客户端上,您需要使用SSL_set_tlsext_host_name
设置服务器名称。
在服务器上,因为你处理回调而更加复杂。有关示例,请参阅Serving multiple domains in one box with SNI。
快速评论:
method = SSLv23_client_method();
...尝试过TLSv1_2_client_method()方法
理想情况下,你可以这样做:
SSL_library_init();
SSL_load_error_strings();
const SSL_METHOD* method = SSLv23_method();
if(NULL == method) handleFailure();
SSL_CTX* ctx = SSL_CTX_new(method);
if(ctx == NULL) handleFailure();
/* Cannot fail ??? */
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
SSL_CTX_set_options(ctx, flags);
...
SSLv23_method
可以获得SSLv2及更高版本。然后删除你不想要的东西,比如SSLv2,SSLv3和压缩。这使您获得TLS 1.0及更高版本(TLS 1.3即将到来,因此您无需更改源代码即可获得)。您将获得服务器支持的最高协议(例如,TLS 1.2)。
另一方面,这只会让你获得TLS 1.2:
SSL_library_init();
SSL_load_error_strings();
const SSL_METHOD* method = TLSv1_2_client_method();
if(NULL == method) handleFailure();
这意味着您将无法连接到运行TLS 1.0的服务器(与许多IIS服务器一样)。 如果使用ECC连接到Google服务器,则需要确保禁用压缩。否则,您将失败,因为Google在使用带有ECC的TLS 1.2时必须禁用压缩。
如果您发表评论:
/* ---------------------------------------------------------- *
* Set SSLv2 client hello, also announce SSLv3 and TLSv1 *
* ---------------------------------------------------------- */
你会使用以下内容,但我不推荐它:
long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_TLS1_1 | SSL_OP_NO_TLS1_2;
我不推荐它,因为它禁用了TLS 1.2和TLS 1.1;它启用SSLv3。 2014年没有SSLv3的理由。
又一个评论......
务必使用SSL_CTX_set_cipher_list
设置密码套件。选择你最喜欢的16个左右,忽略其余部分。对于其中的文档(以及DHE-RSA-AES256-SHA
等密码套件的名称),请参阅SSL_CTX_set_cipher_list(3)
和ciphers(1)
。
选择16个左右的密码套件可实现两个目标。首先,它确保您得到您想要的。其次,它确保像F5或IronPort这样的旧设备不会窒息。较旧的设备使用固定大小的缓冲区,并且该缓冲区对于具有80多个密码套件的ClientHello
而言太小。如果有16或20个密码套件,ClientHello
会通过。
最后一条评论......
1.1.0之前的OpenSSL 不执行主机名匹配。但是,它确实执行其他常规检查。因此,如果您使用1.0.2或更低版本,则必须执行主机名匹配。有关检查的信息,请参阅OpenSSL wiki上的SSL/TLS Client。