使用Stunnel根据GOST-2012算法对TLS流量进行加密


在本文中,我想展示如何配置Stunnel以在TLS协议中使用俄罗斯加密算法。 另外,我将向您展示如何使用Rutoken EDS 2.0加密核心中实现的GOST算法对TLS通道进行加密。


但是首先,让我们弄清楚Stunnel的用途。 简而言之-这是一个程序,您可以在该程序上在服务器和客户端之间转移流量加密的整个逻辑。 这样做如下:假设您有一个客户端和一个服务器,它们彼此通信,而无需使用加密,身份验证和完整性检查。 您可以重写客户端和服务器,以便所有传出消息和传入消息都在它们之间进行传输,同时考虑到所有这些要点,但是如果您可以将其简单地转移到另一个应用程序的肩膀上,那么为什么会有这样的困难呢? 为了解决这个问题,Stunnel是正确的。


您只需要配置客户端,使其所有流量都传输到客户端Stunnel,反过来,它会建立与服务器的安全连接,并将数据发送到服务器Stunnel。 服务器上的Stunnel解密传入的流量,并将数据重定向到服务器输入。 通过查看此图可以轻松实现以上内容。



值得注意的是,服务器不必完全是Stunnel,即可使用加密算法。 很好的是,有现成的演示台支持俄罗斯加密技术, RusCrypto'2019演示文稿中列出了这些演示台


我们需要提供双向身份验证的稳定服务器。
我们已选择CryptoPro服务器作为最可靠的服务器,并全面实施了GOST TLS标准。 感谢他们的帮助:)


听起来很简单,让我们尝试组织这个过程。


准备步骤


我们将需要:


  1. Openssl
  2. 漏斗
  3. 引擎
  4. 访问CryptoPro测试服务器以验证TLS连接

Windows的OpenSSL可以从此处获取 ,对于Linux用户可以从存储库获取,也可以通过从此处下载最新版本组装自己。 也可以从Rutoken SDK中获取,也可以从openssl \ openssl-tool-1.1目录中获取,此归档文件将对我们进一步有用,因为 它包含了我们感兴趣的rtengine。 可以在这里找到Stunnel。 操作需要版本> = 5.56。


您可以从Rutoken SDK下载rtengine,它位于openssl \ rtengine \ bin目录中 。 您需要将其放置在存储所有openssl引擎的位置。 您可以使用以下方法找到他们的方式


openssl.exe version -a 

但是仅将引擎移动到所需的文件夹是不够的;您仍然需要配置openssl本身才能使用它。 我们找出配置文件openssl.cnf所在的位置与上述命令相同(在Windows stunnel下具有自己的openssl版本,因此配置文件位于path到\ stunnel \ config \ openssl.cnf


 #   : openssl_conf = openssl_def ... #   : # OpenSSL default section [openssl_def] engines = engine_section [engine_section] rtengine = rtengine_section [rtengine_section] engine_id = rtengine dynamic_path = /path/to/rtengine.so MODULE_PATH = /usr/lib/librtpkcs11ecp.so default_algorithms = CIPHERS, DIGEST, PKEY, RAND 

让我们验证rtengine是否已连接,为此,我们连接一个令牌并列出所有加密算法:


 openssl ciphers -v 

让我提醒您,在Windows中,您需要检查tunnel旁边的openssl
如果其中存在我们的GOST,则说明一切设置正确。


现在到了最有趣的时刻了:检查与GOST测试服务器CryptoPro的连接。 这些服务器的列表在此处( https://www.cryptopro.ru/products/csp/tc26tls )中进行了描述。 这些服务器中的每一个都使用自己的身份验证和加密算法。 此外,在端口443、1443、2443等上启动了仅接受某些参数的服务。 因此,例如,在http://tlsgost-256auth.cryptopro.ru上 ,使用算法GOST2012-GOST8912-GOST8912和256位密钥通过身份验证执行加密。 此外,端口443使用XchA-ParamSet,端口1443使用XchB-ParamSet,端口2443使用A-ParamSet,依此类推。


现在我们知道了我们需要哪个密钥,让我们从测试服务器获取根证书,制定出可以使用的密钥,并签署对我们证书的请求。


简单方法(在Windows和Linux下工作)


  1. 为了获得根证书,我们将转到测试CA LLC“ CRIPTO-PRO”的网站 。 然后单击按钮以获得证书。 将出现一个新选项卡,您需要在该选项卡上选择Base64加密方法,然后单击“下载CA证书”按钮。 结果certnew.cer文件保存。
  2. 按照链接 。 安装我们要求的所有插件。 我们单击按钮“创建密钥” ,然后选择生成算法“ GOST R 34.10-2012 256位”。 接下来,创建一个证书请求,在“应用程序”列中,您可以选择所有内容。 在“其他应用程序”列中:客户端身份验证和CryptoPro注册中心用户。
  3. 我们再次打开测试CA的站点,但是这次我们单击按钮“发送以Base64编码的就绪请求PKCS#10或PKCS#7” 。 我们将请求的内容粘贴到该字段中,单击“问题”按钮,并以Base64格式加载user.crt证书。 结果文件被保存。

通过命令行


  1. 为了获得根证书,我们将转到测试CA LLC“ CRIPTO-PRO”的网站 。 然后单击按钮以获得证书。 将出现一个新选项卡,您需要在其中选择Base64加密方法,然后单击“下载CA证书”按钮。 结果certnew.cer文件保存。


  2. 现在生成密钥。


     pkcs11-tool --module /usr/lib/librtpkcs11ecp.so --keypairgen --key-type GOSTR3410-2012-256:B -l --id 45 # 45 --   ASII id  (E) 

    值得注意的是,令牌上生成的密钥不能从令牌中复制。 这是其使用的主要优点之一。


  3. 创建证书请求:


     openssl req -engine rtengine -new -key="pkcs11:id=E" -keyform engine -out client.req 

  4. 我们再次打开测试CA的站点,但是这次我们单击按钮“发送以Base64编码的就绪请求PKCS#10或PKCS#7” 。 我们将请求的内容粘贴到该字段中,单击“发出”按钮,然后以Base64格式上载user.crt证书。 结果文件被保存。



最后一个问题是:为什么所有这些??? 为什么我们得到所有这些证书,密钥和请求?


事实是,TLS协议需要使用它们进行双向身份验证。 它的工作非常简单。


我们有一个服务器证书,我们认为它是受信任的。


我们的客户验证我们正在使用的服务器具有类似的证书。
服务器希望确保与认识的用户一起使用。 为此,我们创建了一个证书请求以使用我们的密钥。


我们发送了此请求,服务器使用其数字签名对其进行了签名。 现在,我们可以每次都显示此证书,该证书由根CA签名,从而确认我们是我们。


配置隧道


只是为了正确配置我们的隧道。 为此,请使用默认的Stunnel设置创建一个stunnel.conf文件,并在其中写入以下内容:


 ;      - debug = 7 output = /path/to/stunnel.log ;    TLSv1 sslVersion=TLSv1 ;  . engine=rtengine ;     [remote system] client=yes ;  engine,     engineId=rtengine ;   2 (  ) verify = 2 ;     CAFile = /path/to/certnew.cer ;     cert=/path/to/user.crt ;     . key=pkcs11:model=Rutoken%20ECP;manufacturer=Aktiv%20Co.;id=E ;   Stunnel      accept = localhost:8080 connect = tlsgost-256auth.cryptopro.ru:2443 

现在,如果一切都正确完成,则可以使用我们的配置启动Stunnel并连接到服务器:


 stunnel.exe /path/to/stunnel.conf 

打开浏览器,然后转到localhost:8080。 如果一切正确,那么将显示以下内容:



如果不是,那么我们查看日志并使用调试器来了解问题所在。


如有任何疑问,欢迎发表评论:)

Source: https://habr.com/ru/post/zh-CN477650/


All Articles