前言
为了应对日益增长的网络安全挑战, 越来越多的互联网厂商已经陆续开始或者已经彻底停止了对 SSL 3 / TLS 1.0 / TLS1.1 等上古加密算法的支持. 而对于一些同样拥有悠久历史的和 AWS 服务相关联的应用程序, 是否可以通过仅更新 SDK 版本的方式来适应新的环境. 本文将以 Windows Server 2008 R2 + .NET Framework 4.0 作为基础环境, 使用 VB.NET 和最新版本 AWS SDK 尝试开发一个能够访问 S3 存储桶的 WinForm 应用进行可行性测试.
环境准备
在本地使用 VMware/VirtualBox 安装一台 Windows Server 2008 R2 虚拟机并安装 Visual Studio 2010 开发环境.
相关 ISO 镜像下载链接:
filename: cn_windows_server_2008_r2_standard_enterprise_datacenter_and_web_with_sp1_vl_build_x64_dvd_617396.iso
md5: 38992812F82E594644B2D64CCD86F89C
ed2k://|file|cn_windows_server_2008_r2_standard_enterprise_datacenter_and_web_with_sp1_vl_build_x64_dvd_617396.iso|3368962048|7C210CAC37A05F459758BCC1F4478F9E|/filename: cn_visual_studio_2010_ultimate_x86_dvd_532347.iso
md5: A94B54AA4A79E4F767DE116B1B77473D
ed2k://|file|cn_visual_studio_2010_ultimate_x86_dvd_532347.iso|2685982720|4AE6228933DDE49D9BFA4C3467C831C2|/
踩坑过程
由于 Visual Studio 2010 还未内置 NuGet 包管理工具, 首先需要手动下载安装 NuGet Package Manager
启动 Visual Studio 2010, 创建 .NET Framework 4 Windows 窗体应用程序项目
从工具箱中拖拽设计一个简单的窗体: 一个用来触发操作的按钮和 TextBox1
用来作为测试结果的输出
Ctrl+Shift+S 保存项目, 工具 > NuGet 程序包管理器 > 管理解决方案的 NuGet 程序包
展开左侧 联机
- nuget.org
检查可用程序包, 结果直接报错了, 看起来可能在这一步就开始遇到了通信问题
先忽视这个问题, 手动从网站下载包文件离线方式安装吧. 分别下载 AWSSDK.S3 和 AWSSDK.Core
将下载好的两个 .nupkg
文件放到一个文件夹中
回到 VS2010 打开 NuGet 程序包管理设置
在程序包源中添加指向上面存放 .nupkg
的文件夹, 添加后记得点 更新
按钮. 同时取消勾选默认的 nuget.org 的源
再次管理解决方案的 NuGet 程序包, 直接安装 AWSSDK - S3
期间会自动解决依赖关系把 AWSSDK - Core Runtime
也给装上
终于可以开始进入撸代码的环节了, 双击窗体设计器中的按钮打开代码视图, 完成后的 Form1.vb
代码如下:
Imports Amazon
Imports Amazon.S3
Imports Amazon.S3.ModelPublic Class Form1Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.ClickDim accessKey As String = "YourAccessKey"Dim secretKey As String = "YourSecretKey"Dim bucketName As String = "YourBucketName"Dim awsCredentials As New Amazon.Runtime.BasicAWSCredentials(accessKey, secretKey)Dim s3Client As New AmazonS3Client(awsCredentials, RegionEndpoint.CNNorthWest1)Dim listObjectsRequest As New ListObjectsRequest()listObjectsRequest.BucketName = bucketNameTryDim response As ListObjectsResponse = s3Client.ListObjects(listObjectsRequest)TextBox1.AppendText("Listing S3 Bucket's objects:" + vbCrLf)For Each obj In response.S3ObjectsTextBox1.AppendText(obj.Key + vbCrLf)NextCatch ex As AmazonS3ExceptionTextBox1.Text = ex.MessageEnd TryEnd Sub
End Class
F5 启动调试, 点击 TEST
按钮, 程序卡顿一下后出现 TLS 的报错信息:
Amazon S3 will stop supporting TLS 1.0 and TLS 1.1 connections. Please update your client to use TLS version 1.2 or above. To learn more and to update your client, see https://go.aws/3AUlVSb. For further assistance, contact AWS support.
填坑过程
好吧, 还好本来就有思想准备, 毫不意外的坑在了 TLS 的版本问题上, 开始尝试填坑. 看起来 .NET Framework 4.0 跑的应用默认并没有走 TLS 1.2 通信. 关于 Windows Server 2008 R2 和 .NET Framework 4.0 开启 TLS 1.2 的文档很多, 基本上都是要安装补丁或者修改注册表什么的, 尝试手动下载和折腾了半天都不好使. 意外发现网上有大神整理好的 Windows 7 / Server 2008 R2 的累积更新包 UpdatePack7R2-23.8.10 还挺新鲜的, 装了半天并重启了几次才算完全安装完成.
安装前请务必确认 C 盘的可用空间至少有 10 GB 以上
装完累积更新包后再检查 Windows 更新居然还能正常检查到有新的可用更新, 果断继续更新, 又是漫长的等待…
更新全部都装完以后, 再次测试还是相同的错误. 为了验证通信到底走的是啥版本的 TLS, 用 WireShark 抓个包瞅瞅.
果然还是走了 TLSv1, 不过继续抓包用 IE 访问 https://www.qq.com 发现 Windows 系统现在已经是能够支持 TLSv1.2 的
参考文档 SecurityProtocolType Enum 可以确认是 .NET Framework 4.0 只支持 SSL 3.0 和 TLS 1.0
仍不死心, 由于 Windows 中可以共存多个版本的 .NET Framework, 死马当成活马医, 再下个 4.5.2 的版本 Microsoft .NET Framework 4.5.2 (Offline Installer) 装上之后, 再运行调试, 奇迹发生!
程序可以正常执行了, 再次启用 NuGet 线上的源, 也可以正常使用了.
总结
在 Windows Server 2008 R2 + .NET Framework 4.0 (Only) 的环境中, 由于 .NET Framework 4.0 先天不足无法支持 TLS 1.2 所以即便是 Windows 安装更新可以在系统层面(IE)支持 TLS 1.2, 使用 .NET Framework 4.0 开发的应用也无法正常通过 TLS 1.2 进行通信. 额外安装 .NET Framework 4.5.2 与 4.0 形成共存状态后, 之前基于 4.0 开发的应用就可以正常使用 TLS 1.2 通信了.
总的来说, 其实主要需要做的就两件事情:
- 把 Windows Server 2008 R2 能更的新都更一遍
- 额外安装 .NET Framework 4.5.2 与 4.0 共存, 弥补 4.0 的先天缺陷
附录
SSL / TLS 的历史版本发布时间:
RFC 7568 相关描述 1
The Secure Sockets Layer version 3.0 (SSLv3), as specified in RFC 6101, is not sufficiently secure. This document requires that SSLv3 not be used. The replacement versions, in particular, Transport Layer Security (TLS) 1.2 (RFC 5246), are considerably more secure and capable protocols.
AWS 于 2023.6.28 将会把 TLS 1.2 作为调用 API 时的最低版本要求 2
June 1, 2023: This blog post has been updated to add a timeline to clarify the key dates. To avoid a disruption to your AWS workloads, you must update all of your TLS 1.0/ 1.1 software clients no later than 06/28/23.
Microsoft 也在 2023.8.1 的博客中宣布 Windows 即将默认禁用 TLS 1.0 / 1.1 3
Transport Layer Security (TLS) is the most common internet protocol for setting up an encrypted channel of communication between a client and server. TLS 1.0 dates back to 1999 and, over time, several security weaknesses have been found in this protocol version. TLS 1.1 was published in 2006 and made some security improvements, but never saw broad adoption. These versions have long been surpassed by TLS 1.2 and TLS 1.3, and TLS implementations try to negotiate connections using the highest protocol version available.
RFC 7568 ↩︎
TLS 1.2 to become the minimum TLS protocol level for all AWS API endpoints ↩︎
TLS 1.0 and TLS 1.1 soon to be disabled in Windows ↩︎