设置支持SNI的TLS1.2连接
我们正在尝试设置TLS1.2连接。 已经在Macbook下载了最新的OpenSSL。 使用此代码创buildTLS1.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”,引用来自:sslconnect-7aa462.o中的_main
如果有人可以协助创buildTLS1.2连接,然后从目标C调用(如果需要对套接字编程进行一些特殊处理),那将是非常有帮助的。
[请注意,我不是一个iOS的人。 我正在帮助一个团队解决问题。 也是自己的socket编程新手,虽然团队有一些经验。
尝试了TLSv1_2_client_method()方法,但它给出了下面的链接错误:
体系结构x86_64的未定义符号:“_TLSv1_2_client_method”,引用来自:sslconnect-7aa462.o中的_main
好吧,这听起来像你正在连接到x86_64
,但你需要iOS。 您可以使用以下两个命令validation架构:
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是iOSdebugging器。
注意 : /usr/local/ssl/ios/
是我在安装OpenSSL for iOS之后创build的。 苹果不提供它。
如果你没有四个iOS架构,那么你有两个select。 首先,您可以基于“OpenSSL FIPS对象模块用户指南” (第122页,附录E.2)中的iOS过程进行构build。
其次是从GitHub下载预build版本。 这是一个由OpenSSL 1.0.1h使用OpenSSL的程序构build的noloader的GitHub。 这里有另一个来自Stefan Arentz ,似乎很受欢迎,但它的OpenSSL 1.0.1g。
然后从目标C调用
C和Objective C一起工作得很好。调用它没什么特别的。
…支持iPhone应用程序的SNI
在客户端上,您将需要使用SSL_set_tlsext_host_name
设置服务器名称。
在服务器上,因为处理callback而涉及更多。 有关示例,请参阅使用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服务器,则需要确保禁用压缩。 否则,你会失败,因为谷歌有一个奇怪的要求,即在使用带有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
设置您的密码套件。 select你最喜欢的16个左右,并忽略其余的。 对于它的文档(以及DHE-RSA-AES256-SHA
等密码套件的名称),请参阅SSL_CTX_set_cipher_list(3)
和ciphers(1)
。
select16个左右的密码套件实现了两个目标。 首先,它确保你得到你想要的。 其次,它确保像F5或IronPort这样的旧设备不会窒息。 较旧的设备使用固定大小的缓冲区,对于具有80多个密码套件的ClientHello
,该缓冲区太小。 ClientHello
通过,如果有16或20密码套件。
最后一点评论
1.1.0之前的OpenSSL 不会执行主机名匹配。 但是,它确实执行了其他的习惯性检查。 所以如果你是1.0.2或更低,你将不得不执行主机名匹配。 有关检查的信息,请参阅OpenSSL wiki上的SSL / TLS客户端 。