◆周明华 杨海云 吴鑫哲 李婉桃
国密算法JSSE密码套件的设计与实现
◆周明华 杨海云 吴鑫哲 李婉桃
(中国民航大学计算机科学与技术学院 天津 300300)
随着网络安全对国家安全重大影响,国家密码管理局发布了国家商用密码算法SM系列并制订了《国密SSL VPN技术规范》,而目前SSL和TLS协议只支持国际密码算法实现数据安全传输。经研究发现国密算法的优良性能并不逊于DES、RSA等国际密码算法,甚至性能和密钥位数更为突出,使用国密算法的网络安全传输协议对我国网络安全技术实现自主可控具有重要意义。本文通过在OpenJDK添加并注册国密算法服务提供者,并在JSSE开源提供者中扩展国密标准TLS密码套件,设计实现基于JSSE框架的国密标准TLS密码套件。
国密算法;TLS;JSSE;CSP;密码套件
为保障国家重要领域信息安全,近年来国家有关机构从国家安全和长远战略的角度提出了推动国密算法应用实施和加强行业安全自主可控的要求。建设行业网络安全环境,增强我国行业信息系统的“安全可控”能力显得尤为必要和迫切。国家密码管理局发布了国家商用密码算法SM系列并制订了《国密SSL VPN技术规范》,国家信息安全制度逐渐被完善。然而,目前在SSL和TLS协议中,还未正式进行对国产密码算法的扩展。此项工作旨在SSL和TLS协议中,添加国密标准的TLS密码套件。JSSE为Java版本的SSL和TLS协议提供了框架和实现,我们基于JSSE提出了一种在TLS协议中添加国密标准的TLS密码套件的设计方案,实现符合国密标准的TLS协议,对国家信息化建设的自主可控具有重要意义。
本文的主要贡献有三方面:
(1)我们研究了JSSE框架和JCA/JCE的原理,阐述了JSSE和JCA/JCE及其之间的关系。
(2)在OpenJDK中,添加并注册了名为CAUC_CSTA的国密算法服务提供者,实现了HmacSM3校验算法和SM4对称加密算法。
(3)在开源SunJSSE提供者中扩展了国密标准TLS密码套件TLS_RSA_WITH_SM4_SM3,实现了TLS协议在握手和交互中使用国密算法。
在本文以下的部分,我们首先阐述了JSSE和JCA/JCE及其之间关系以及TLS国密标准,然后提出了JSSE国密算法的设计方案以及方案实施过程,最后对本文进行了总结,并对今后的工作进行了展望。
通过网络传输的数据能会被非预期接收者的人轻松访问,为了确保信息在网络传输过程中的机密性和完整性,安全套接层(SSL)和传输层安全性(TLS)协议旨在保护数据在网络上传输时的机密性和完整性。Java安全套接字扩展(JSSE)为Java版本的SSL和TLS协议提供了框架和实现,并包括数据加密、服务器身份验证、消息完整性和可选客户端身份验证的功能。通过JSSE,开发人员可以在客户机和任何运行应用程序协议(如HTTP、Telnet和FTP)的服务器之间通过TCP/IP安全传输数据。JSSE使用JCA中定义的相同“提供者”体系结构,使其具有实现独立性与算法独立性。OpenJDK默认使用SunJSSE作为JSSE的服务提供者,由JCA/JCE密码服务提供者(CSP)完成JSSE中的安全加密服务。SunJSSE默认情况下使用SunJCE实现所有的密码算法,可以通过在安全属性文件里注册JCA/JCE的CSP,扩展其他的密码算法。
国密算法即国家密码管理局认定的国家商用密码算法。我国国家密码管理局近些年陆续发布了自主研发的密码算法标准。于2010年12月17日发布的SM3算法,是一种密码散列函数标准,主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,摘要长度为256位。SM4算法,是国家密码管理局于2012年3月21日发布的一种分组密码标准,主要用于数据加密,分组长度,密钥长度均为128位。
国家密码局在TLSv1.1的版本基础上,针对国内现状,发布了《国密SSL VPN技术规范》,此标准基于国密SSL的技术协议,对产品功能、性能和管理作出了相关规定,并定义了一系列国密套件。在此项工作中我们选中TLS_RSA_WITH_SM4_SM3国密标准密码套件完成设计与实现。
JSSE和JCA/JCE的框架中是由实现JCA/JCE的CSP提供JSSE中的安全加密服务的,然而在JSSE中并不支持国密标准TLS协议的密码算法套件,为了使JSSE支持国密标准的TLS协议,我们设计了一种在不改变JSSE框架的条件下实现国密标准TLS协议的密码算法套件方案。方案步骤如下,流程图见图1。
图1 设计方案流程图
步骤1:基于JCA/JCE的“提供者”架构,建立支持国密算法的CSP,命名为CAUC_CSTA。继承服务提供者接口(SPI)实现HmacSM3校验算法和SM4对称加密算法,并将它们注册为CSP的HmacSM3和SM4算法的实现类。
步骤2:在OpenJDK中通过“%JAVA_HOME%jrelibsecurityjava.security”文件静态注册密码服务提供者CAUC_CSTA。
步骤3:在开源JSSE服务提供者SunJSSE中修改其代码,添加国密标准的TLS密码套件别名TLS_RSA_WITH_SM4_SM3,建立国密标准的TLS密码套件TLS_RSA_WITH_SM4_SM3与CSP实现的密码算法HmacSM3和SM4之间的关系。
(1)JCA/JCE简介:JCA/JCE是Java平台提供的安全加密服务框架。它们不实现密码算法,只定义了一组加密服务接口。而加密算法的实现是基于“提供者”架构创建相应的CSP,继承SPI实现相应算法的实现类,并建立CSP所定义的密码算法与实现类之间的关系。
(2)SM4算法实现:为了在数据传输时能够使用SM4作为数据加密算法,我们通过继承javax.crypto.CipherSpi类来编写SM4类,其需要实现的SPI方法有engineSetMode、engineSetPadding、engineInit,engineDoFinal等,在这些方法里面实现初始化和完整的加密、解密算法。
(3)HmacSM3算法实现:为了使用HmacSM3作为数据验证算法,我们通过继承javax.crypto.MacSpi来编写HmacSM3类,其需要实现的SPI方法有engineInit、engineUpdate、engineDoFinal等,在这些方法里实现哈希算法的初始化和哈希值的更新和计算。
(4)CSP创建:通过继承javax.crypto.Provider类来创建CSP,需要设置名称和版本号等基本信息,为相关算法指定具体实现的类,如put(“Cipher.SM4”, “org.me.provider.SM4”),这样就完成了SM4加密算法的实现指定,当用户调用如Cipher.getinstance(“SM4”)时,就能得到相应实例。我们可以将CSP生成一个jar包以方便使用。当用户将该CSP加入到Java环境中时,就能够调用到相应算法。
(5)CSP注册:我们通过静态注册的方式安装CSP,通过配置JRE,修改%JDK_Home%jrelibsecurityjava.security文件,新增一行org.me.provider.CaucCstaProvider,之后导入CSP的jar包到Java环境中,将其放入%JRE_Home%libext目录中。
3.3.1 国密标准密码套件扩展
通过实现对JSSE框架及其提供者SunJSSE的研究,SSLSocketImpl类依赖SSLSessionImpl类,SSLSessionImpl类依赖CipherSuite类预定义TLS协议所用的校验算法、加密算法,并调用CipherSuite类的静态方法add预定义所有密码套件CipherSuite类对象集合。
添加国密标准TLS密码套件TLS_RSA_WITH_SM4_SM3方式是在sun.security.ssl.CipherSuite类进行预定义密码套件的静态代码块中添加代码:
add("TLS_RSA_WITH_SM4_SM3", 0xe01a, --p, K_RSA, B_SM4, N)。
通过以上代码会创建该密码套件对象并将其添加进CipherSuite类对象集合中。在创建过程中,需要扩展HmacSM3和SM4算法,扩展方式见3.3.2和3.3.3。
3.3.2 HmacSM3算法扩展
在CipherCuite类中,校验算法是通过相应的校验算法名作为静态常量CipherSuite$MacAlg类对象名称预定义每一种校验算法;通过CipherSuite$MacAlg类的macAlg对象确定在数据传输过程中所用的校验算法;通过CipherSuite$MacAlg类的newMac工厂方法创建使用时sun.security.ssl.MAC类对象。
MAC类对象包含javax.crypto.Mac引擎类对象属性,是由sun.security.ssl.JSSEJce类的getMac静态方法创建,是真正用来做校验算法的引擎类。Mac类归属于JCA/JCE,正是通过这种方式JSSE调用了JCA/JCE中的数据校验服务,我们通过创建JCA/JCE含有HmacSM3算法的CSP和修改JSSE代码实现了在JSSE中使用HmacSM3算法作为TLS协议中的校验算法,含HmacSM3算法的CSP创建已在3.2说明。JSSE的修改步骤如下:
步骤1:在CipherSuite类中预定义MacAlg类名为M_SM3的静态常量,相应位置添加代码:
final static MacAlg M_SM3 = new MacAlg("SM3",32,64,9)
步骤2:对CipherSuite类的构造函数中添加对HmacSM3校验算法的判别,使其在创建含HmacSM3算法的密码套件时将M_SM3对象引用给macAlg对象,进而作为数据传输过程中的校验算法,相应位置添加代码:
if (name.endsWith("_SM3")) { macAlg = M_SM3;}
步骤3:对MAC类的构造函数中添加对HmacSM3校验算法的判别,使在JSSEJce类通过getMac静态方法创建Mac引擎类对象时成功实例化HmacSM3算法,在相应位置添加代码:
if (macAlg == M_SM3) {algorithm = "HmacSM3";}
3.3.3 SM4算法扩展
在CipherCuite类中,对称加密算法是通过相应的加密算法名作为静态常量CipherSuite$BulkCipher类对象名称预定义每一种加密算法;通过CipherSuite$BulkCipher类的cipher对象确定在数据传输过程所用的对称加密算法;通过CipherSuite$BulkCipher类的newCipher工厂方法创建使用时sun.security.ssl.CipherBox类对象。newCipher方法是通过调用CipherBox类的newCipherBox静态工厂方法创建CipherBox类对象。
CipherBox类对象包含javax.crypto.Cipher引擎类对象属性,其是由JsseJce的getCipher静态方法创建,是真正用来做加密算法的引擎类。Cipher类归属于JCA/JCE,正是通过这种方式JSSE调用了JCA/JCE中的对称加密服务,我们通过创建JCA/JCE含有SM4算法的CSP和修改JSSE代码实现了在JSSE中使用SM4算法作为TLS中的对称加密算法,含SM4算法的CSP创建已在3.2说明。
JSSE的修改方式是在CipherSuite中预定义BulkCipher类对象名为B_SM4的静态常量,在相应位置添加代码:
final static BulkCipher B_SM4 = new BulkCipher(CIPHER_SM4,BLOCK_CIPHER, 16, 16, 0, true);
从而在创建与之对应的密码套件时将定义数据传输过程中的cipher对象被引用为B_SM4对象。
3.3.4 密码套件测试
我们创建基于TLS的安全服务器和安全客户端,分别使用SSLServerSocket和SSLSocket类来创建安全套接字进行通讯,通过指定TLS_RSA_WITH_SM4_SM3密码套件来进行Echo协议测试,使用Java提供的keytool工具生成所需的RSA证书,并在TLS握手事件完成后输出套接字所使用的密码套件。由调试数据图4可见服务器和客户端通讯过程中所使用的密码套件为TLS_RSA_WITH_SM4_SM3,由图2客户端与图3服务端可见,TLS握手顺利完成。与我们预想的一致,能够正确完成整个数据交互过程。
本文笔者提出了一种使JSSE支持国密标准的TLS协议密码套件的设计方案,此方案在不改变JSSE框架的条件下,通过对开源的SunJSSE进行了密码套件扩展以及注册实现国密算法的CSP,成功实现了JSSE对国密标准TLS协议的密码算法套件的支持。在未来,我们将加入SM2非对称加密算法,创建独立的JSSE服务提供者,它将支持国密证书的制作与解析,实现更多的国密标准TLS协议的密码算法套件。
图2 客户端
图3 服务端
图4 调试数据
[1][英] Ivan Ristic.HTTPS权威指南[M].北京:人民邮电出版社,2016.
[2]刘平等.SSL VPN 技术规范[M].北京:中国标准出版社,2014.
[3]吴永强.国密SSL安全协议通信协议的研究与实现[D].西安:西安电子科技大学,2014.
[4]罗钰.深入浅出Linux TCP/IP协议栈[M].北京:人民邮电出版社,2010.
[5]贾猛等.支持国密算法的安全套接层协议扩展方法: 中国,104394179[P/OL].2014-12-18.
大学生创新创业训练项目(项目编号:IECAUC2018013)。