Apache APISIX 玩转 Tongsuo 国密插件

本文通过解读国密的相关内容与标准,呈现了当下国内技术环境中对于国密功能支持的现状。并从 API 网关 Apache APISIX 的角度,带来有关国密的探索与功能呈现。

作者:罗泽轩,Apache APISIX PMC

什么是国密

顾名思义,国密就是国产化的密码算法。在我们日常开发过程中会接触到各种各样的密码算法,如 RSA、SHA256 等等。为了达到更高的安全等级,许多大公司和国家会制定自己的密码算法。国密就是这样一组由中国国家密码管理局制定的密码算法。在国际形势越发复杂多变的今天,密码算法的国产化替代,在一些领域已经成为了一股势不可挡的潮流。

国密的官方名称为国家商用密码,简称商密,拼音缩写是 SM。这也是国密标准中 SM2/3/4/7/9 等算法名称的来源。国密算法的命名方式非常简单直接,就像“绵阳九所”、“二机部”一样,都是“分类+序号”的组合。其中 SM1 和 SM4 是对称算法,对标 AES;SM2 是非对称算法,对标 RSA、ECDSA;SM3 是摘要算法,对标 MD5;等等。由于本文并非涉及到国密的实现细节,所以不会讲得非常细,也就科普下国密算法的分类。

在基础的国密算法之上,我们可以构造一个国密的垂直生态,比如实现国密算法的硬件、提供国密支持的密码库、加入国密流程的 TLS 握手协议等等。正如安全需要纵深防御一样,基于国密的信任链也需要有全软件栈上的支持。

因此,当我们谈论国密支持时,并不仅仅单独指可以用某一种国密算法进行加解密,而是指嵌合入国密的生态,支持某种国密的应用场景。

国密的应用场景

作为国家密码管理局制定的密码算法,国密广泛应用于电子政务(包括国家政务通、警务通等重要领域)、信创及金融业的各个应用领域。

  • 政府和金融的身份认证终端。依照现行有关规定,许多涉及政府和金融的身份认证终端(诸如 USBKey、智能 IC 卡、银行卡终端等)都需要提供对国密的支持。
  • 国产开源操作系统。许多主打国产替代的开源操作系统,会提供基于国密的安全加固功能。比如龙蜥操作系统 (Anolis OS) 提到自己实现了全栈国密能力;OpenEuler 也在做国密相关的一些功能,比如基于国密数字证书扩展了 EFI 的数字签名。
  • 信创产品。还有许多做信创生意的厂商,围绕国密推出符合相关标准的产品。例如支持使用国密算法做数字签名的 PDF 工具、支持国密接入标准的音视频软件等等。
  • 基于国密 TLS 协议的生态。也是在日常开发中接触得最多的。譬如各种国产 CA 厂商、支持了国密TLS的许许多多密码库和浏览器,以及国密接入的VPN和网关等等。

    APISIX 对国密的探索与支持

Apache APISIX 是一个动态、实时、高性能的 API 网关,提供负载均衡、动态上游、灰度发布、精细化路由、限流限速、服务降级、服务熔断、身份认证、可观测性等数百项功能。作为一个发迹于国内环境的 API 网关,APISIX 自然需要考虑下如何接入国密的生态圈。

由于国密更多地用在国内环境中,尚未被 OpenSSL 等国际主流项目所完全接纳。如果要使用国密的功能,就涉及到更换 APISIX 默认的 OpenSSL 库为其他 SSL 库。

为此,我们考察了以下的项目:

  • GMSSL:北京大学开源的项目。原版基于 OpenSSL 1.0.2 修改而来。新的 GMSSL 3.0 基本上是重新开发,跟 OpenSSL 的目录结构差别很大。
  • gm-BoringSSL:个人开源项目,在 BoringSSL 上增加国密支持。已有两年未改动。
  • TaSSL:北京江南天安科技有限公司开源的项目。基于 OpenSSL 1.1.1 修改而来。
  • Tongsuo:蚂蚁集团开源的项目。基于 OpenSSL 3.0 修改而来,项目前身是 BabaSSL,现已 改名为铜锁/Tongsuo。 由于 GMSSL 3.0 并不基于 OpenSSL,即使能保证 API 兼容,也没办法确保能 100% 替换现有 OpenSSL 的行为,所以被首先排除。其次 gm-BoringSSL 疏于维护,也被排除。

在 TaSSL 和 Tongsuo 之中,我倾向于选择 Tongsuo[1]。因为 Tongsuo 在标准上拥有更强的话语权,比如 RFC 8998(TLS 1.3 中支持 SM 套件)就是由 Tongsuo 的开发者制定的。TaSSL 则是每出一个版本,就公布一个新的仓库。比如前一个 版本[2],感觉不太靠谱。

对于选择 Tongsuo,我个人存在一个顾虑,就是他目前基于 OpenSSL 3.0 的版本还没有发布正式的 Release 版本(第一个版本预计在 2023 年 2 月发布)。由于 Tongsuo 当前还没有一个固定的版本,因此社区决定先把国密相关的功能独立出来,以插件形式存在,有相关需求时可单独启用。

目前已在插件层面实现了服务端一侧国密双证书的支持,感兴趣的读者可以在官网查看 gm 插件介绍文档 插件介绍文档[3],自行完成 APISIX 的编译和对应插件的安装配置工作。当然,如果想即刻预览该插件的使用过程,也可以直接参考下文内容。

快速参考:APISIX 国密插件的使用 

启用插件

插件要求 Apache APISIX 运行在编译了 Tongsuo 的 APISIX-Base 上

首先需要安装 Tongsuo (此处我们选择编译出 Tongsuo 的动态链接库):

# TODO: use a fixed release once they have created one.
# See https://github.com/Tongsuo-Project/Tongsuo/issues/318
git clone https://github.com/api7/tongsuo --depth 1
pushd tongsuo
./config shared enable-ntls -g --prefix=/usr/local/tongsuo
make -j2
sudo make install_sw

其次需要构建 APISIX-Base,让它使用 Tongsuo 作为 SSL 库:

export OR_PREFIX=/usr/local/openresty
export openssl_prefix=/usr/local/tongsuo
export zlib_prefix=$OR_PREFIX/zlib
export pcre_prefix=$OR_PREFIX/pcre

export cc_opt="-DNGX_LUA_ABORT_AT_PANIC -I${zlib_prefix}/include -I${pcre_prefix}/include -I${openssl_prefix}/include"
export ld_opt="-L${zlib_prefix}/lib -L${pcre_prefix}/lib -L${openssl_prefix}/lib64 -Wl,-rpath,${zlib_prefix}/lib:${pcre_prefix}/lib:${openssl_prefix}/lib64"
./build-apisix-base.sh

该插件默认是禁用状态,你需要将其添加到配置文件./conf/config.yaml 中才可以启用它:

plugins:
  - ...
  - gm

由于 APISIX 的默认 cipher 中不包含国密 cipher,所以我们还需要在配置文件 ./conf/config.yaml 中设置 cipher:

apisix:
  ...
  ssl:
    ...
    # 可按实际情况调整。错误的 cipher 会导致 “no shared cipher” 或 “no ciphers available” 报错。
    ssl_ciphers: HIGH:!aNULL:!MD5

配置完成后,重新加载 APISIX,此时 APISIX 将会启用国密相关的逻辑。

测试插件

在测试插件之前,需要准备好国密双证书。Tongsuo 提供了生成 【SM2 双证书】 的 教程[4]。

在下面的例子中,我们将用到如下的证书:

# 客户端加密证书和密钥
t/certs/client_enc.crt
t/certs/client_enc.key

# 客户端签名证书和密钥
t/certs/client_sign.crt
t/certs/client_sign.key

# CA 和中间 CA 打包在一起的文件,用于设置受信任的 CA
t/certs/gm_ca.crt

# 服务端加密证书和密钥
t/certs/server_enc.crt
t/certs/server_enc.key

# 服务端签名证书和密钥
t/certs/server_sign.crt
t/certs/server_sign.key

此外,还需要准备 Tongsuo 命令行工具。

./config enable-ntls -static
make -j2
# 生成的命令行工具在 apps 目录下
mv apps/openssl ..

你也可以采用非静态编译的方式,不过就需要根据具体环境,自己解决动态链接库的路径问题了。以下示例展示了如何在指定域名中启用 gm 插件。 要在指定域名中启用 gm 插件的功能,需要先创建对应的 SSL 对象:

#!/usr/bin/env python
# coding: utf-8

import sys
# sudo pip install requests
import requests

if len(sys.argv) <= 3:
    print("bad argument")
    sys.exit(1)
with open(sys.argv[1]) as f:
    enc_cert = f.read()
with open(sys.argv[2]) as f:
    enc_key = f.read()
with open(sys.argv[3]) as f:
    sign_cert = f.read()
with open(sys.argv[4]) as f:
    sign_key = f.read()
api_key = "edd1c9f034335f136f87ad84b625c8f1"
resp = requests.put("http://127.0.0.1:9180/apisix/admin/ssls/1",json={
    "cert": enc_cert,"key": enc_key,"certs": [sign_cert],"keys": [sign_key],"gm": True,"snis": ["localhost"],},headers={
    "X-API-KEY": api_key,})
print(resp.status_code)
print(resp.text)

然后将上面的脚本保存为 ./create_gm_ssl.py,运行以下命令:

./create_gm_ssl.py t/certs/server_enc.crt  t/certs/server_enc.key t/certs/server_sign.crt t/certs/server_sign.key

输出结果如下:

200
{"key":"\/apisix\/ssls\/1","value":{"keys":["Yn...

完成上述准备后,可以使用如下命令测试插件是否启用成功:

./openssl s_client -connect localhost:9443 -servername localhost -cipher ECDHE-SM2-WITH-SM4-SM3 -enable_ntls -ntls -verifyCAfile t/certs/gm_ca.crt -sign_cert t/certs/client_sign.crt -sign_key t/certs/client_sign.key -enc_cert t/certs/client_enc.crt -enc_key t/certs/client_enc.key

其中,./openssl 是上文提到的 Tongsuo 命令行工具,9443 是 APISIX 默认的 HTTPS 端口。 如果一切正常,可以看到连接已经建立了起来,并输出如下信息:

...
New,NTLSv1.1,Cipher is ECDHE-SM2-SM4-CBC-SM3
...

禁用插件

如果不再使用此插件,可将 gm 插件从 ./conf/config.yaml 配置文件中移除,然后重启 APISIX 或者通过插件热加载的接口触发插件的卸载。

相关链接 

如果你对该功能或者插件感兴趣,欢迎在随时在社区进行交流。

[1] https://github.com/Tongsuo-Project/Tongsuo

[2] https://github.com/jntass/TASSL-1.1.1k

[3] https://apisix.apache.org/zh/docs/apisix/next/plugins/gm/

[4] https://www.yuque.com/tsdoc/ts/sulazb

本文由博客一文多发平台 OpenWrite 发布!

原文地址:https://blog.csdn.net/ApacheAPISIX" target="_blank" rel="noopener" title="Apache_APISIX_中文社区">Apache_APISIX_中文社区</a> <img class="article-time-img article-heard-img" src="https://c

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


可以认为OpenFeign是Feign的增强版,不同的是OpenFeign支持Spring MVC注解。OpenFeign和Feign底层都内置了Ribbon负载均衡组件,在导入OpenFeign依赖后无需专门导入Ribbon依赖,用做客户端负载均衡,去调用注册中心服务。
为进一步规范小程序交易生态、提升用户购物体验、满足用户在有交易的小程序中便捷查看订单信息的诉求,自2022年12月31日起,对于有“选择商品/服务-下单-支付”功能的小程序,需按照平台制定的规范,在小程序内设置订单中心页。开发者可通过小程序代码提审环节,或通过「设置-基础设置-小程序订单中心path设置」模块设置订单中心页path。1、 新注册或有版本迭代需求的小程序,可在提审时通过参数配置该商家小程序的订单中心页path。2、无版本迭代需求的小程序,可在小程序订单中心path设置入口进行设置。
云原生之使用Docker部署Dashdot服务器仪表盘
本文主要描述TensorFlow之回归模型的基本原理
1.漏洞描述Apache Druid 是一个集时间序列数据库、数据仓库和全文检索系统特点于一体的分析性数据平台。Apache Druid对用户指定的HTTP InputSource没有做限制,并且Apache Druid默认管理页面是不需要认证即可访问的,可以通过将文件URL传递给HTTP InputSource来绕过。因此未经授权的远程攻击者可以通过构造恶意参数读取服务器上的任意文件,造成服务器敏感性信息泄露。2.影响版本Apache Druid &lt;= 0.21.13...
内部类(当作类中的一个普通成员变量,只不过此成员变量是class的类型):一个Java文件中可以包含多个class,但是只能有一个public class 如果一个类定义在另一个类的内部,此时可以称之为内部类使用:创建内部类的时候,跟之前的方法不一样,需要在内部类的前面添加外部类来进行修饰 OuterClass.InnerClass innerclass = new OuterClass().new InnerClass();特点:1.内部类可以方便的访问外部类的私有属性...
本文通过解读国密的相关内容与标准,呈现了当下国内技术环境中对于国密功能支持的现状。并从 API 网关 Apache APISIX 的角度,带来有关国密的探索与功能呈现。作者:罗泽轩,Apache APISIX PMC什么是国密顾名思义,国密就是国产化的密码算法。在我们日常开发过程中会接触到各种各样的密码算法,如 RSA、SHA256 等等。为了达到更高的安全等级,许多大公司和国家会制定自己的密码算法。国密就是这样一组由中国国家密码管理局制定的密码算法。在国际形势越发复杂多变的今天,密码算法的国产化
CENTOS环境Apache最新版本httpd-2.4.54编译安装
Apache HTTPD是一款HTTP服务器,它可以通过mod_php来运行PHP网页。影响版本:Apache 2.4.0~2.4.29 存在一个解析漏洞;在解析PHP时,将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。我们查看一下配置:读取配置文件,前三行的意思是把以 结尾的文件当成 文件执行。问题就在它使用的是 符号匹配的,我们都知道这个符号在正则表达式中的意思是匹配字符串的末尾,是会匹配换行符的,那么漏洞就这样产生了。 进入容器里,打开index.php,发现如果文件后缀名为 php、
apache Hop现在好像用的人很少, 我就自己写一个问题收集的帖子吧, 后面在遇到什么问题都会在该文章上同步更新
2.启动容器ps:注意端口占用,当前部署在 8080 端口上了,确保宿主机端口未被占用,不行就换其他端口ps:用户名和密码都是 admin,一会用于登录,其他随便填5.下载一个官方提供的样例数据库【可跳过】ps:此步国内无法访问,一般下载不了,能下的就下,不能下的跳过就行了,一会配置自己的数据库7.访问登录页面ps:注意端口是上面自己配置的端口,账号密码是 admin依次点击 Settings → Database Connections点击 DATABASE 就可以配置自己的数据库了
String类的常用方法1. String类的两种实例化方式1 . 直接赋值,在堆上分配空间。String str = "hello";2 . 传统方法。通过构造方法实例化String类对象String str1 = new String("Hello");2.采用String类提供的equals方法。public boolean equals(String anotherString):成员方法 str1.equals(anotherString);eg:publi
下载下载地址http://free.safedog.cn下载的setup:安装点击下面的图标开始安装:可能会提示:尝试先打开小皮面板的Apache服务:再安装安全狗:填入服务名:如果服务名乱写的话,会提示“Apache服务名在此机器上查询不到。”我干脆关闭了这个页面,直接继续安装了。安装完成后,需要进行注册一个账户,最后看到这样的界面:查看配置:...
一、问题描述一组生产者进程和一组消费者进程共享一个初始为空、大小n的缓冲区,只有缓冲区没满时,生产者才能把资源放入缓冲区,否则必须等待;只有缓冲区不为空时,消费者才能从中取出资源,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入资源,或一个消费者从中取出资源。二、问题分析(1)、关系分析。生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者只能才能消费,它们还是同步关系。(2)、整理思路。只有生产生产者和消费者进程,正好是这两个进程
依赖注入的英文名是Dependency Injection,简称DI。事实上这并不是什么新兴的名词,而是软件工程学当中比较古老的概念了。如果要说对于依赖注入最知名的应用,大概就是Java中的Spring框架了。Spring在刚开始其实就是一个用于处理依赖注入的框架,后来才慢慢变成了一个功能更加广泛的综合型框架。我在学生时代学习Spring时产生了和绝大多数开发者一样的疑惑,就是为什么我们要使用依赖注入呢?现在的我或许可以给出更好的答案了,一言以蔽之:解耦。耦合度过高可能会是你的项目中一个比较
<dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>使用人数最多的版本</version></dependency>importorg.apache.velocity.Template;importorg.apache.velo
Java Swing皮肤包前言:一.皮肤包分享二.皮肤包的使用1.先新建一个项目。2.导入皮肤包1.先导入我们刚刚下载的jar文件,右键项目demo即可2.如果右键没有这个选项,记得调为下图模式3.点击下图蓝色圆圈处4.找到刚刚下载的jar文件,点击打开即可5.我们看一下效果,是不是比原生的好看前言:因为Java Swing自身皮肤包不是很好看,甚至有点丑,怎么让你的界面更加好看,这里就需要用到皮肤包,我发现了一个还不错的皮肤包,让你的界面美观了几个等级。废话不多说。一.皮肤包分享百度网盘分享链接:
一、前言在做Java项目开发过程中,涉及到一些数据库服务连接配置、缓存服务器连接配置等,通常情况下我们会将这些不太变动的配置信息存储在以 .properties 结尾的配置文件中。当对应的服务器地址或者账号密码信息有所变动时,我们只需要修改一下配置文件中的信息即可。同时为了让Java程序可以读取 .properties配置文件中的值,Java的JDK中提供了java.util.Properties类可以实现读取配置文件。二、Properties类Properties 类位于 java.util.Pro
Mybatis环境JDK1.8Mysql5.7maven 3.6.1IDEA回顾JDBCMysqlJava基础MavenJunitSSM框架:配置文件的最好的方式:看官网文档Mybatis1、Mybatis简介1.1 什么是Mybatis如何获得Mybatismaven仓库:中文文档:https://mybatis.org/mybatis-3/zh/index.htmlGithub:1.2 持久化数据持久化持久化就是将程序的数据在持久状态和瞬时状态转