当Java遇上机密计算
凌云时刻
编者按:作者 / 汪少军 编辑 / 芹菜 出品 / 云巅论剑
写在前面
在信息世界里,数据存在三种状态: 存储态、传输态和计算态。存储在数据库或磁盘中的数据属于存储状态,在网络中传输的数据属于传输状态,正在被计算处理的数据属于计算状态。我们需要从数据三种状态出发进行系统的安全保护,才能确保真正的数据安全。对于存储态和传输态数据安全问题,我们可以利用被广泛使用的数据加密技术进行有效保护。对于计算态的数据安全保护仍旧属于新的前沿领域。
全球主流的芯片厂商都纷纷推出了各自的机密计算解决方案,比如Intel SGX和Arm TrustZone等。TrustZone主要用在终端领域,而SGX技术则可以应用于服务器领域。SGX技术能够提供极高的机密计算保护等级,但由于SGX技术在内存资源和编程模型上的限制,无法有效支撑Java生态的机密计算业务,不得不说是一个遗憾。随着阿里云神龙架构第七代ECS实例的发布,所搭载的Intel新一代SGX2技术,为我们构建基于Java生态的机密计算服务提供了条件。
Java机密计算Demo演示
现在,让我们通过一个具体的例子来演示如何为Java业务提供机密计算保护。该实例基于第三代神龙架构第七代ECS实例构建,在SGX2提供的机密计算可信执行环境内运行Java SpringBoot网络服务。
准备工作
申请一台支持SGX2的神龙架构第七代ECS实例,EPC内存规格不要过小24G; 下载LibOS: Occlum容器镜像 occlum/occlum:0.20.0-ubuntu18.04; 下载JDK: Alibaba Dragonwell11(Alpine),Alibaba发布的基于Alpine平台Dragonwell11镜像版本; 下载SpringBoot源码: Demo,该Demo展示了一个基于SpringBoot框架构建的简单网络服务;
java -jar spring-boot-0.0.1-SNAPSHOT.jar
构建SGX执行环境
首先登录到ECS实例;
在ECS环境下,通过docker命令进入Occlum容器;
-v `pwd`:`pwd` \
-v /dev/sgx_enclave:/dev/sgx/enclave \
-v /dev/sgx_provision:/dev/sgx/provision \
-v /var/run/aesmd:/var/run/aesmd \
occlum/occlum:0.20.0-ubuntu18.04
在Occlum容器中,创建一个enclave实体。该实例包含一个json配置文件和image镜像文件夹;
cd occlum_instance
occlum init
4. 对Occlum.json文件进行修改,修改内容包括堆的大小、entry point和env环境变量等;
resource_limits.kernel_space_heap_size="64MB"
resource_limits.max_num_of_threads = 64
process.default_heap_size = "256MB"
process.default_mmap_size = "1400MB"
entry_points = [ "/usr/lib/jvm/java-11-alibaba-dragonwell/jre/bin" ]
env.default = [ "LD_LIBRARY_PATH=/usr/lib/jvm/java-11-alibaba- \
dragonwell/jre/lib/server:/usr/lib/jvm/java-11-alibaba-dragonwell/jre/lib:/usr/lib/jvm/java-11- \
alibaba-dragonwell/jre/../lib" ]
运行Java需要配置更大的内存空间。entry_points选项表示Occlum LibOS里面JDK的放置路径。JDK的路径必须是xx/xx/jre/bin模式,而且需要设置LD_LIBRARY_PATH环境变量。由于目前的Occlum LibOS还不支持exec系统调用,因此JDK的路径需要满足一定条件,这样可以避免JVM虚拟机启动时出现exec系统调用。
进入image文件夹,在此目录下创建usr/lib/jvm/java-11-alibaba-dragonwell文件目录,用于放置Dragonwell11 Alpine JDK,注意将JDK压缩文件解压后的文件夹名重命名为jre,保证与.json配置文件一致;创建usr/lib/spring文件目录,用于放置之前准备的SpringBoot spring-boot-0.0.1-SNAPSHOT.jar文件。
注意,image文件目录将作为SGX LibOS运行起来后的根目录。
将Occlum容器环境下的libz.so.1文件拷贝到image/lib;
构建image机密镜像;
启动SGX机密计算业务;
UseCompressedOops -XX:MaxMetaspaceSize=64m -Dos.name=Linux -jar /usr/lib/spring/spring- \
boot-0.0.1-SNAPSHOT.jar
SpringBoot启动完成后,使用命令curl localhost:8080请求SpringBoot服务,得到 "Greetings from Spring Boot!" 的回复,表示运行成功。其中,-XX:-UseCompressedOops参数是为了优化Java在Occlum下的启动时间;-Dos.name=Linux参数是为了告知JVM虚拟机LibOS的系统类型;
整个SpringBoot网络服务的运行过程都在机密计算环境下进行,ECS实例自带的底层软件没有权限对保护中的服务进行窥探,实现了云上服务的运行态数据保护。
神龙架构第七代ECS与Java机密计算
阿里云发布的神龙架构第七代ECS实例,其搭载的是Intel第三代至强可扩展处理器(代号为Ice Lake)。该处理器提供的下一代Intel SGX安全技术(SGX2),在核数和EPC内存容量上皆有非常可观的提升,具体规格见图(2)所示。Ice Lake处理器在核数上提供了最多80物理核(160逻辑核)的处理能力,而第一代SGX可用处理器至多只有6个物理核;EPC内存容量则增加到了1TB,而第一代SGX EPC内存容量只有128M。用户可根据需求选择不同规格的核数和EPC内存容量。
图(2) SGX技术规格对比图
由于SGX1提供的EPC内存容量和核数太少,不适应Java这种比较重的编程语言。长期以来,只有基于C/C++这类native语言更适合在SGX1中运行。此外,SGX SDK定义的Host Enclave编程模型,需要将业务代码进行分割,对代码侵入性较大,进一步限制了SGX1的使用范围。由于SGX2技术在核数和EPC内存容量上的提升,使得我们可以突破Host Enclave编程模型的束缚,同时满足Java业务对硬件资源的要求,基于SGX部署Java机密计算业务成为了可能,可以预期公有云场景下的机密计算服务会迎来蓬勃发展。
机密计算模型
机密计算编程模型
图(3) 机密计算编程模型
int function(int a, int b) {
return a + b;
}
int main() {
... ...
enclave ec = create_enclave();
int c = function(&enclave, 3, 5);
destroy_enclave(ec);
... ...
printf("sum is: %d\n", c);
}
另一种是Full-Feature编程模型,它将整个完整的应用都放到Enclave中运行,Host只负责Enclave的管理和ocall等操作,一般由底层框架的工具链提供,用户不用感知Host的存在;该编程模型与传统编程模型一致,无需进行分割,没有增加额外的编程难度,对已有业务代码进行改造也很容易。但该模型需要在Enclave中驻留一个功能强大的SDK或LibOS,才能支撑完整应用的正常运行,加上业务代码自身的体量,会导致Enclave中TCB较大,安全等级下降。
int function(int a, int b) {
return a + b;
}
int main() {
int c = function(3, 5);
printf("sum is: %d\n", c);
}
机密计算需求模型
鱼和熊掌不可兼得,需要在易用性和安全性两个需求维度进行取舍。我们将机密计算业务需求按照安全等级进行分级,不同安全等级的需求,选择不同的编程模型,见图(4)所示。当业务中只有少量计算逻辑需要安全保护,且要求较高的安全等级时,可以选择Host-Enclave编程模型;当用户不希望对业务代码进行大量改造,同时可以接受相对较低的安全等级时,可以选择Full-Feature编程模型。
图(4) 机密计算需求模型
SGX SDK
Intel在发布第一代SGX技术之时,就推出了Intel SGX SDK,它定义了面向C/C++语言的SGX机密计算Host-Enclave编程模型,用.edl文件定义Host与Enclave之间的交互接口;之后微软云Azure推出了OpenEnclave,它是对Intel SGX SDK进行的功能扩展和平台抽象。可以在Enclave中运行更加复杂的业务,同时扩展了安全计算硬件平台的支持(SGX和TrustZone等);Google云推出了Asylo编程模型,与OpenEnclave类似,同样是进行了平台抽象和功能扩展。Asylo最大的特点是将Encalve抽象成一种远端服务,与Host通过GRPC方式进行交互。可以让Host和Enclave两个模块在物理上分离,不必限制在一个芯片内部,而且还屏蔽了Host和Enclave的编程语言差异,使得Asylo编程模型更具灵活性,非常具有借鉴意义。
纵观Intel SGX SDK、OpenEnclave和Asylo的发展,不难看出OpenEnclave和Asylo是对Intel SGX SDK的继承和发展,上述三种SDK满足了部分机密计算应用场景,比如使用C/C++语言编写且只有少量计算需要安全保护的业务场景。又由于Enclave SDK能力限制,无法支持复杂Enclave业务逻辑。主要有如下几个特点:
都属于Host-Enclave编程模型,Asylo在一定程度上也支持Full-Feature编程模型;
开发难度大,Host-Enclave编程模型需要对应用程序做二分;
仅支持C/C++编程语言,无法支持像Java/Go等高级编程语言;
不支持Full-Feature编程模型,无法满足易用性要求高的业务场景;
SGX LibOS
SGX运行环境与普通运行环境有许多不同之处,是否可以在Enclave中引入一个OS屏蔽掉SGX执行环境的差异,让应用程序感知不到SGX的存在,就像在普通环境下运行一样呢?业界有很多这样的先行者,目前比较知名的SGX LibOS项目有Occlum、Graphene和SGX-LKL等。其中Occlum是由蚂蚁自研的开源TEE-OS系统,采用Rust编程语言,功能较完善,已支持多种编程语言,同时还具备高性能和内存安全等特点。
SGX LibOS的目的是让整个应用方便的运行在SGX Enclave中,符合Full-Feature机密计算编程模型,易用性高、支持多种编程语言和复杂的应用。这种解决方案主要存在以下问题:
TCB增大,牺牲了一定的安全性;
需要消耗更多的SGX硬件资源;
频繁的ecall和ocall操作(比如IO)影响业务性能;
随着神龙架构第七代ECS实例的发布,来到SGX2时代后,得益于核数和EPC内存大小的提升,基于Java编程语言的机密计算服务具备了实用的条件。
Java机密计算解决方案
Alibaba Dragonwell11 musl版本不仅仅可以作为机密计算JDK的首选版本,而且还能用于构建Alpine容器镜像,有效减小容器镜像的大小。
Java机密计算性能评估
总结
你可能还想看
1. 智能告警——企业IT系统神经中枢
2. 工作7年,我的10条经验总结
3. OAM 与 KubeVela 项目整体捐赠进入 CNCF,让云端应用交付更加简单
4. 龙蜥社区首届理事大会圆满召开!14家理事代表出席
5. 仅用 480 块 GPU 跑出万亿参数,中文最大规模多模态预训练模型发布
关注「凌云时刻」
每日收获前沿技术与科技洞见