腾讯Kona国密套件(Tencent Kona SM Suite)基于JDK的标准Service Provider Interface(SPI)实现了从基础算法簇,到公钥基础设施(PKI),再到安全通信协议的全链路国密特性。该套件已在GitHub上开源:https://github.com/Tencent/TencentKonaSMSuite(点击阅读原文)
腾讯Kona国密套件包含四个Java Security Provider:
-
KonaCrypto,它是一个Java Cryptography Extension(JCE)实现,遵循标准的Java Cryptography Architecture(JCA)框架实现了国密基础算法SM2,SM3和SM4。
-
KonaPKIX,它实现了国密证书的解析及其证书链验证,并可加载和创建包含国密证书的密钥库(Key Store)文件。
-
KonaSSL,它实现了中国的传输层密码协议(TLCP),并遵循RFC 8998规范将国密基础算法应用到了TLS 1.3协议中。
-
Kona,它没有直接实现任何功能,而是将KonaCrypto,KonaPKIX和KonaSSL中的特性进行了简单的封装,以方便用户仅使用这一个Provider就能够调用上述三个Provider中的全部功能。一般地,建议使用这个Provider。
许可协议
腾讯Kona国密套件使用的许可协议是GNU GPL v2.0 license with Classpath Exception,这也正是OpenJDK使用的许可协议。
系统要求
操作系统
腾讯Kona国密套件为纯Java编写,可以支持任何能够运行JDK的操作系统平台,也能够支持Android平台。
JDK版本
支持JDK的全部三个长期支持(LTS)版本,即8,11和17。
值得注意的是,任何JCE实现必须要先获得由Oracle颁发的JCE代码签名证书才能运行在Oracle JDK上。而腾讯Kona国密套件已经取得了该证书,并且它的jar文件均使用该证书进行了签名,所以该套件也可以运行在Oracle JDK上。
不过,我们非常期待您能选择腾讯的OpenJDK发行版,即Tencent Kona JDK,其提供了8,11和17三大LTS版本,并支持Linux,macOS和Windows等主流操作系统,以及x86_64和aarch64等主流CPU架构。Tencent Kona JDK依托腾讯的海量生产级实践,针对大数据,云计算,机器学习等场景进行了大量的定制优化。
构建
腾讯Kona国密套件使用Gradle进行构建,其脚本使用Kotlin DSL。该Gradle项目包含有四个子模块:kona-crypto,kona-pkix,kona-ssl和kona-provider,它们分别对应于四个Provider:KonaCrypto,KonaPKIX,KonaSSL和Kona。
构建该项目的一个典型方法就是在该项目的根目录下执行命令:
-
gradle build
它会编译源代码,并执行单元测试,最后制作出jar文件。也可以仅构建某个子模块,比如像下面这样:
-
gradle :kona-pkix:build
安装
腾讯Kona国密套件的所有制品(jar文件)都已经上传到了Maven中央仓库。一般地,只需要在项目的构建脚本中把它们声明为依赖就可以了。比如,在Gradle的构建脚本中可以有如下的依赖声明:
-
-
-
-
-
-
-
-
-
repositories { mavenCentral()}dependencies { implementation("com.tencent.kona:kona-crypto:1.0.4") implementation("com.tencent.kona:kona-pkix:1.0.4") implementation("com.tencent.kona:kona-ssl:1.0.4") implementation("com.tencent.kona:kona-provider:1.0.4")}
注意,并不一定要将所有的Provider都加到类路径中,请根据实际需求去声明依赖。例如,若只需要使用国密的基础算法,且想统一地使用Provider名称Kona时,那么依赖声明可能就像下面这样:
-
-
-
-
dependencies { implementation("com.tencent.kona:kona-crypto:1.0.4") implementation("com.tencent.kona:kona-provider:1.0.4")}
加载Provider
在使用腾讯Kona国密套件提供的特性之前,需要先加载它的Provider。推荐加载KonaProvider,如下所示:
-
Security.addProvider(new KonaProvider());
上述语句会将KonaProvider加到Provider列表的最后一位,其优先级为最低。如有必要,也可以将它插入到列表的指定位置,如下所示:
-
Security.insertProviderAt(new KonaProvider(), n);
其中n的值越小,优先级越高,最小可为1。
特性
下面将会介绍腾讯Kona国密套件的主要特性:
基础算法簇
腾讯Kona国密套件中的KonaCrypto实现了国密的基础算法簇,包括SM2,SM3和SM4。
SM2
SM2是一个基于椭圆曲线(ECC)的非对称加密算法。实现该算法需要遵循如下的中国国家标准:
-
GB/T 32918.1-2016 第1部分:总则
-
GB/T 32918.2-2016 第2部分:数字签名
-
GB/T 32918.3-2016 第3部分:密钥交换协议
-
GB/T 32918.4-2016 第4部分:公钥加密算法
-
GB/T 32918.5-2017 第5部分:参数定义
KonaCrypto实现了JDK定义的KeyPairGeneratorSpi,SignatureSpi,CipherSpi和KeyAgreementSpi接口,以提供SM2密钥对生成,SM2签名,SM2加密和SM2密钥交换等特性。使用这些算法与使用JDK自带的其它密钥对生成算法(如ECKeyPairGenerator),签名算法(如SHA256withECDSA),非对称加密算法(如RSA)和密钥协商算法(如ECKeyAgreement)是非常相似的。
需要特别强调的是,SM2密钥交换协议与通常的ECDH密钥协商有很大的不同。SM2密钥交换协议要求双方各有两个密钥对:一个是长期密钥对,一般认为它来源于证书所使用的密钥对;另一个是短期密钥对,相当于通常的ECDHE算法使用的即时(Ephemeral)密钥对。另外,每一方还需要有各自的ID,如果没有的话,就使用默认的1234567812345678。另外,SM2密钥交换协议还要求区分是哪一方首先发起的交换,这一方被称为发起方(Initiator),另一方则为响应方(Responder)。
SM3
SM3是一个密码学安全的哈希算法。实现该算法需要遵循如下的中国国家标准:
- GB/T 32905-2016:SM3密码杂凑算法
KonaCrypto实现了JDK定义的MessageDigestSpi和MacSpi接口,以提供SM3哈希和SM3HMac消息验证码等算法。使用这些算法与使用JDK自带的其它哈希算法(如SHA-256)和消息验证码算法(如HmacSHA256)是非常相似的。
SM4
SM4是一个分组加密算法。实现该算法需要遵循如下的中国国家标准:
- GB/T 32907-2016:SM4分组密码算法
KonaCrypto为SM4支持了四种分组操作模式:
-
CBC(Cipher Block Chaining),密码块链接模式
-
CTR(Counter),计数器模式
-
ECB(Electronic codebook),电子密码本模式
-
GCM(Galois/Counter Mode),伽罗瓦/计数器模式。
另外,还为CBC和ECB这两种操作模式实现了PKCS#7填充规范。
那么,支持了如下的Cipher参数组合(Transformation):
-
SM4/CBC/NoPadding:使用CBC分组操作模式,不使用填充。明文或密文的长度必须是16字节的整数倍。
-
SM4/CBC/PKCS7Padding:使用CBC分组操作模式,且使用PKCS#7填充。明文或密文的长度可以不是16字节的整数倍。
-
SM4/CTR/NoPadding:使用CTR分组操作模式,不使用填充。明文或密文的长度可以不是16字节的整数倍。
-
SM4/ECB/NoPadding:使用ECB分组操作模式,不使用填充。明文或密文的长度必须是16字节的整数倍。
-
SM4/ECB/PKCS7Padding:使用ECB分组操作模式,且使用PKCS#7填充。明文或密文的长度可以不是16字节的整数倍。
-
SM4/GCM/NoPadding:使用GCM分组操作模式,不使用填充。明文或密文的长度可以不是16字节的整数倍。
为了提供上述特性,KonaCrypto实现了JDK定义的CipherSpi接口。使用SM4算法与使用JDK自带的其它分组加密算法(如AES)是非常相似的。
对于KonaCrypto的具体用法,请参见该GitHub项目中kona-crypto子模块的README和示例:
-
kona-crypto/README_cn.md
-
kona-crypto/src/test/java/com/tencent/kona/crypto/provider。
公钥基础设施(PKI)
腾讯Kona国密套件中的KonaPKIX基于JDK的Public Key Infrastructure(PKI)特性实现了对使用国密算法(SM2椭圆曲线和SM3withSM2签名算法)的X.509证书的解析,证书链验证,以及密钥库文件的读取与创建。在证书链验证中,还支持了证书吊销列表(CRL)和在线证书状态协议(OCSP)特性。为密钥库文件支持了标准的PKCS#12与JDK独有的JKS这两种格式。
为了提供上述特性,KonaPKIX实现了JDK定义的CertificateFactorySpi,KeyStoreSpi,CertPathBuilderSpi和SignatureSpi等接口。
对于KonaPKIX的具体用法,请参见该GitHub项目中kona-pkix子模块的README和示例:
-
kona-pkix/README_cn.md
-
kona-pkix/src/test/java/com/tencent/kona/pkix/demo
安全通信协议
腾讯Kona国密套件中的KonaSSL综合地利用了上面的国密基础算法与PKI特性,实现了中国的传输层密码协议(TLCP)和国际的RFC 8998规范。
传输层密码协议(TLCP)
TLCP是中国基于TLS 1.1和1.2协议定制而成的协议,对应的中国国家标准为:
- GB/T 38636-2020:传输层密码协议
该协议与TLS协议的最重大区别,就是要求通信端提供两个证书:认证证书和加密证书。其中认证证书与TLS协议使用的证书功能类似,用于对通信端的身份进行验证。而加密证书则为TLCP协议独有,它只会用于密钥交换。
KonaSSL除了支持TLCP协议的"双证书"模式,还实现了它定义的密码套件ECC_SM4_GCM_SM3(0xE053),ECC_SM4_CBC_SM3(0xEC13),ECDHE_SM4_GCM_SM3(0xE051)和ECDHE_SM4_CBC_SM3(0xE011)。需要了解的是,当使用ECDHE密码套件时,客户端也必须提供双证书,这是SM2密钥交换算法所要求的,也是与TLS协议中的ECDHE密码套件的一个明显区别。
KonaSSL的TLCP实现不仅支持完整握手(Full Handshaking),也支持会话重用(Session Resumption)。而且不仅支持了传统的基于Session ID的会话重用,还支持了较新的基于Session Ticket的会话重用。后者会显著地减小服务端的压力,所以它也是KonaSSL的默认会话重用模式。
KonaSSL还为TLCP实现了一些重要的TLS扩展,如,服务器名称指示(SNI),它会帮助服务器选择正确的证书;应用层协议协商(ALPN),它会用于在握手时协商使用HTTP/2协议。
RFC 8998
RFC 8998规范将国密算法要素应用到了TLS 1.3协议中。KonaSSL实现了该规范定义的椭圆曲线curveSM2(41),签名机制sm2sig_sm3(0x0708)和密码套件TLS_SM4_GCB_SM3(0x00C6)。
为了提供上述特性,KonaSSL实现了JDK定义的SSLContextSpi等接口。为了能利用上KonaSSL实现的国密安全通信协议特性,其关键点就是让JDK的SSLSocket或SSLEngine能利用上KonaSSL实现的SSLContext实例。
上述安全通信协议的实现能够与其它方的实现,如蚂蚁集团的铜锁(原BabaSSL)和江南天安的TASSL,基于TLCP和TLS 1.3协议进行安全通信,这表明KonaSSL的实现是符合规范的。KonaSSL还能够与主流的Java组件,如Jetty,Netty和Apache Http Client,进行集成。
对于KonaSSL的具体用法,请参见该GitHub项目中kona-ssl子模块的README和示例:
- kona-ssl/README_cn.md
- kona-ssl/src/test/java/com/tencent/kona/ssl/demo
质量与安全
作为一款安全领域的基础组件,腾讯Kona国密套件始终高度重视代码质量,并对安全漏洞执零容忍态度。
腾讯Kona国密套件的基础代码来源于OpenJDK的security-libs模块,故其代码风格与OpenJDK保持一致。该套件一直密切跟踪OpenJDK前沿版本中相关模块的代码变化,实时地将其中的缺陷修复和代码改进移植进来,以确保该套件的代码能够紧跟OpenJDK的演进步伐。
特别地,OpenJDK每个季度发布的Critical Patch Update版本都会公布一批安全缺陷的修复。腾讯Kona国密套件也会立即对其中相关的安全缺陷的修复进行移植,以在最短时间内堵上安全漏洞。
除了时刻关注OpenJDK的缺陷与漏洞修复,我们也会自主地进行代码扫描与安全测试。比如,我们较早地发现了BouncyCastle的SM2加密死循环问题,并立即在自有代码中进行了规避。待BouncyCastle 1.72修复了该缺陷之后,我们也第一时间进行了升级。
近期规划
在腾讯Kona国密套件的初始版本中,国密基础算法完全依赖于开源的BouncyCastle。但我们正在逐步地重新开发这些算法,以期获得更好的性能,安全性和代码质量。当前最新的1.0.4版已经重新实现了SM2的KeyPairGenerator和 KeyAgreement,SM3的MessageDigest和HMac,以及SM4的Cipher。后续还会重新实现SM2的Cipher和Signature。在不久的未来,该套件将会完全摒弃BouncyCastle。