如何用Ruby实现Web服务器TLS密码套件支持情况的自动检测?
Ruby实现TLS密码套件检测工具
方案一:使用Ruby内置OpenSSL库(无需额外依赖)
直接利用Ruby自带的openssl和socket模块,遍历所有支持的密码套件并逐个尝试握手,筛选出目标主机支持的套件。
require 'openssl' require 'socket' def scan_supported_tls_ciphers(host, port = 443) # 获取当前Ruby环境支持的所有TLS密码套件名称 available_ciphers = OpenSSL::SSL::SSLContext.new.ciphers.map { |cipher_entry| cipher_entry[0] } supported_ciphers = [] available_ciphers.each do |cipher| begin # 初始化SSL上下文,仅指定当前测试的密码套件 ssl_ctx = OpenSSL::SSL::SSLContext.new ssl_ctx.ciphers = cipher # 建立TCP连接并启动SSL握手 tcp_socket = TCPSocket.new(host, port) ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_ctx) ssl_socket.hostname = host # 启用SNI,适配多域名主机 ssl_socket.connect # 握手成功,记录该密码套件 supported_ciphers << cipher # 关闭连接 ssl_socket.close tcp_socket.close rescue OpenSSL::SSL::SSLError, Errno::ECONNRESET, Errno::EPIPE, Errno::ETIMEDOUT # 握手失败,跳过该套件 next end end supported_ciphers end # 示例调用 target_host = "example.com" result = scan_supported_tls_ciphers(target_host) puts "目标主机 #{target_host} 支持的TLS密码套件:" result.each { |cipher| puts "- #{cipher}" }
关键说明
- SNI支持:设置
ssl_socket.hostname是必要的,现在绝大多数虚拟主机依赖SNI来正确返回对应域名的证书。 - 异常处理:捕获常见的SSL握手错误、连接重置、超时等异常,避免单个套件测试失败导致程序终止。
- 速度优化:默认是串行测试,若要提升速度,可以用线程池并发测试(注意不要触发目标主机的频率限制)。
方案二:使用第三方Gem简化开发
如果不想手动实现握手逻辑,可以使用net-ssl-cipher-scanner这类专门的扫描gem(需先安装:gem install net-ssl-cipher-scanner)。
示例代码:
require 'net/ssl/cipher_scanner' scanner = Net::SSL::CipherScanner.new('example.com', 443) supported_ciphers = scanner.scan puts "支持的密码套件:" supported_ciphers.each { |c| puts "- #{c}" }
注意事项
- 第三方gem可能已经封装了并发扫描、错误处理等逻辑,开发效率更高,但依赖外部库。
- 确保使用的gem维护状态良好,避免依赖废弃库。
内容的提问来源于stack exchange,提问作者Simmo
相关产品推荐
相关产品推荐

