文 / 林子熠,云原生秘密计算 SIG Maintainer
“请问我怎么能力保障 Java 程序内存中明码的平安呢?”
如果你也过有相似的问题,并且在网上搜到一些并不非常欠缺却又无可奈何的答案,阐明你就是 Java 程序安全性问题的 stakeholder。
这个问题的标准答案是 Java 秘密计算技术,它将秘密计算技术引入 Java 的世界,为 Java 程序的安全性带来了重大的晋升。基于此,龙蜥社区云原生秘密计算 SIG 推出了 Java 秘密计算的具体实现技术——Teaclave Java TEE SDK,以下简称 Teaclave Java。该技术具备以下显著长处:
- 全场景安全性。当用户有秘密计算硬件反对时,Teaclave Java 能够实现最高安全等级的 Java 可信计算;当用户没有相干硬件时,进化为平安沙箱隔离级别的可信计算,亦可无效爱护用户的敏感数据和计算过程的安全性。
- 开发和构建简略。基于 SPI 的纯 Java 编程模型,一键式构建,将 Java 秘密计算开发构建门槛一降到底。
Teaclave Java 曾经过企业级外部场景的验证,在 Apache 社区开源。形容本技术的论文由龙蜥社区云原生秘密计算 SIG 与上海交通大学、大连理工大学单干发表在软件工程顶会 ICSE 2023(https://conf.researchr.org/home/icse-2023)上,并且取得了本届会议的 ACM SIGSOFT 卓越论文奖。这是 2020 年以来,龙蜥社区云原生秘密计算 SIG、上海交通大学、大连理工大学首次获此殊荣。
01 问题的实质
这个问题的实质是如何在具备危险的运行时环境中平安地应用敏感数据。当咱们在运行时将明码解密后,明码就会以明文的模式存在于内存中,也就是 Java 的堆上,如图 1 的左半局部所示。如果零碎蒙受攻打,比方 2021 年声名大噪的 log4j 破绽攻打,Java 堆上的内容就会被窃取。即使没有被攻打,在为了性能诊断而做 heap dump 时也有可能被动将敏感信息透露进来。所以将诸如明码这样的平安敏感信息裸露在一般运行环境具备高度的危险。
(图 1 奢侈的 Java 密码保护示意图)
一种爱护思路是尽可能地缩短明文明码在内存中的寄存工夫,以缩短敏感信息裸露的工夫窗口。如图 1 右半局部所示,在应用完明码后,及时将其从内存中销毁,这样会比先前更加平安一些。因为明码是文本信息,会用字符串类 java.lang.String 保留。Java 的 String 是一种 immutable 类型,创立后不能更改内容,所以没有能够重置内容的 API。要销毁明码只能通过反射将 String 类外部保留字符内容的数组内容置空,从而将明码内容从 Java 堆上抹去。间接将明码字符串设置为 null 是没有用的,这样只是把 String 变量的指针设为空,对于 Java 堆上的明码数据没有任何影响,只有等到下次垃圾回收时才有可能将明码数据从堆中革除。另一种办法是用 char 数组保留明码,而不是 String 类,这样就不用调用反射,让销毁更加便当。还有一种办法是用 byte 数组保留明码,因为其明文是字符编码而非人可读的字符,所以会更难被人看懂。
这些就是目前能够从网络上搜到的解决办法,本文将它们称为“奢侈”的 Java 密码保护计划。因为这些计划只是缩短了明文明码在 Java 堆上的生存工夫,并没有真正将明文密码保护起来。而且“及时”一词有很大的弹性,开发人员未必能精确地判断出何时才是及时。
更具备典型性的案例就是驰名的 log4j 破绽问题(https://nvd.nist.gov/vuln/detail/CVE-2021-44228)。攻击者能够利用 log4j 2.14 的破绽将歹意 class 文件上传到服务器并通过 Java 的动静类加载机制运行,从而窃取 Java 堆中保留的服务器私钥。有了私钥,服务器与客户端之间的所有通信内容对于攻击者都如同明文了。
在以上两个例子中,须要在运行时爱护的明码和密钥都是平安敏感的数据。而在理论场景中,爱护范畴并不仅限于敏感数据,还有可能扩充到运算过程。比方鉴权认证场景中,须要保障认证的过程可信,不能被攻击者篡改。再比方云服务的用户将本人的算法部署上云时,尽管部署的制品能够加密,以爱护传输和存储时的平安,云厂商提供了铜墙铁壁的平安防护免得受内部攻打,然而用户仍然会放心云厂商有没有在运行时窥探用户的计算过程,是否存在监守自盗的可能。
由此可见,爱护 Java 利用中的平安敏感数据和运算并不是一件边远的需要,而是具备迫切的现实意义的需要。对于云计算的供应商,让用户置信其敏感数据和运算对于云厂商本人也是不可见的黑盒亦具备重大的商业价值。
02 Java 秘密计算(Confidential Computing)现状
爱护运行时的敏感数据并不是一个陈腐话题,而属于迄今已倒退了 20 多年的技术——秘密计算的一部分。秘密计算是一种提供硬件级的零碎隔离,以保障数据安全和程序运行平安的技术。秘密计算将执行环境划分为富执行环境(Rich Execution Environment,REE)和可信执行环境(Trusted Execution Environment, TEE),认为 REE 和 TEE 应该互相隔离,TEE 须要通过硬件加密以保障外界无奈通晓其中的内容。平安敏感的内容应该放在 TEE 中运行,其余内容则在 REE 中执行。
这套机制早在 1999 年就已提出,不过晚期的硬件加密技术能力无限,仅有反对执行加解密程序的 TPM(可信赖的平台模块,Trusted Platform Module)硬件。2008 年 Arm 公布 TrustZone 技术白皮书,以反对 Arm 平台的通用型秘密计算工作。2015 年 Intel 也推出了带有反对通用利用加密的 SGX(软件保护扩大,Software Guard Extension)芯片的硬件设施,2021 年 SGX 降级为可反对 1T 内存、具备更高性能的 SGX2。
秘密计算的核心理念是在具备被攻打危险的运行时环境中提供一块平安区域供平安敏感程序运行,实现了平安敏感数据和程序在传输、存储和计算全流程的平安可信。目前秘密计算在隐衷平安、区块链、多方计算、IoT 和边缘设施,以及集体计算设施上均有宽泛的利用和广大的前景。
看起来秘密计算技术正是解决 Java 程序安全性问题的标准答案,那么咱们是否可能在 Java 利用中利用秘密计算技术呢?
Occlum – 在 TEE 中放入 JVM 和利用整体
SGX、TrustZone 等为通用型秘密计算提供了硬件根底,Intel、微软等开源的驱动和 SDK 则为通用型秘密计算提供了软件根底。基于这些软硬件根底,开发者曾经能够在软件应用中应用秘密计算。然而秘密计算对于 Java 利用并不敌对,因为 TEE 中只能运行 native 程序,所以 Java 程序并不能间接运行于 TEE 中。要在 TEE 中运行 Java 程序,就必须先在 TEE 中启动一个 JVM,而后在 JVM 上执行 Java 程序。那么是否能在 TEE 中运行 JVM 呢?答案是必定的,那就是 Occlum,其原理如图 2 所示。
Occlum 是介于 TEE 底层 SDK 与 JVM 之间的一层 LibOS,作为操作系统反对一般 JVM 在 TEE 中的运行。用户将蕴含了秘密代码在内的整个 Java 程序部署在 TEE 中,由 Occlum 反对 JVM 执行。图 2 右半局部给出了部署的构造,其中黄色的 APP 代表整个 Java 利用及其所需三方库,红色圆圈代表可信代码。利用通过 REE 中的启动器——通常只是一个很小的命令行工具,启动执行。这种计划的兼容性好,用户根本不须要批改原有代码即可取得秘密计算反对。然而毛病也很显著——放入 TEE 的代码太多,会导致两个问题:
- 安全性降落。本来须要在 TEE 中执行的可信程序可能并不多,然而此计划须要将所有的 Java 程序、三方库、JVM 和 LibOS 全副放入 TEE,导致 TCB(可信计算基,Trusted Computing Base)太大,安全性并不现实。TCB 是平安畛域掂量安全性的重要指标,指信赖的代码量。TCB 越大,其中可能存在安全隐患的代码就越多,程序的安全性就越差,所以 TCB 越小越好。以 log4j 攻打为例,Occlum 依然无奈对其免疫。因为 log4j 库与秘密代码并没有被分隔在不同的执行环境中,而都部署在 TEE 中,所以攻击者上传的歹意类文件也会位于 TEE 中,依然能够从内存中拜访到私钥。
- 性能降落。TEE 的硬件不是通用硬件,与 REE 相比存在性能进化,所以将利用整体放入 TEE 中会导致整个利用的性能降落。但用户本来的需要只是部分加密,为了部分加密而导致整体性能降落会增大利用秘密计算的老本。尽管个别用户能够承受为了平安而产生的局部性能进化,然而对于适度加密产生的额定性能进化会感到难以承受。
(图 2 Occlum 原理示意图)
综上可见,Occlum 计划尽管具备简单易行的劣势,然而其在安全性和性能方面的毛病却是其投入理论利用的次要阻碍。
03 Teaclave Java TEE SDK – 在 TEE 中仅放入可信代码
因为在 TEE 中整体反对 JVM 和全副应用程序的计划会在 TEE 中执行过多的代码,导致安全性和性能降落而难以投入实用,能不能换种思路,仅将可信代码放入 TEE 呢?思考到 TEE 中只能执行 native code,那么是不是能够将可信代码从 Java 代码间接编译为 native code 放入 TEE 运行呢?答案是必定的,这就是本文的配角 Teaclave Java TEE SDK,以下简称 Teaclave Java。
Teaclave Java 是由 JVM 团队开发的 Java 秘密计算开发框架和构建工具链,能够一站式疾速实现 Java 秘密计算利用的开发和构建。退一步思考,即便用户没有反对秘密计算的硬件环境,Teaclave Java 也能够实现平安沙箱隔离,无效保障敏感数据和程序的运行时平安。
Teaclave Java 的关键技术个性有:
1)模块分隔、秘密计算服务化,如图 3 所示。
2)简洁欠缺的秘密计算服务生命周期治理 API。
3)Java 动态编译秘密内容。
4)暗藏实现细节、主动生成所有辅助代码。
在这些技术的反对下,Teaclave Java 可能将从一般模块到秘密模块的 Java 模块间服务调用转为从一般模块到秘密 native 库的函数调用,如图 4 所示。
模块分隔、秘密计算服务化
Teaclave Java 将利用代码分为三个模块,Host、Enclave 和 Common。Host 中是一般的平安非敏感程序,Enclave 中是平安敏感程序,Common 中则是前两者都会用到的公共代码。这种模块划分形式一是为了让开发者感知到代码的安全性辨别,二是为了构建时针对不同模块应用不同工具链的便利性。
Host 和 Enclave 是解耦合的,它们之间只能通过 Java 的 SPI(Service Provider Interface)机制交互,而不能间接调用。秘密计算的实现在 Enclave 模块中被封装成为了服务,其接口申明定义在 Common 模块中,并用 @EnclaveService 注解标识。当 Host 中的程序须要用到某一秘密计算工作时,就能够先加载服务实例,再调用相应的函数。这一构造组织关系如图 3 所示。
(图 3 Teaclave Java 的开发视图)
例如咱们能够在 Common 中申明一个如代码块 1 所示的秘密计算服务接口,其中提供了用于认证加密的明码是否无效的 API,authenticate 函数。该函数承受一个用户传入的加密的明码,返回该明码的认证后果。
@EnclaveService
public interface AuthenticationService {
/**
* Given an encrypted input password, check if it is the correct password.
* @param inputPwd the encrypted password to be authenticated
* @return true if the given password is correct.
*/
boolean authenticate(String inputPwd);
}
(代码块 1 在 Common 模块定义秘密计算服务接口申明示例)
AuthenticationService 接口的具体实现则在 Enclave 模块的 AuthenticationServiceImpl 类中定义,如代码块 2 所示。该类的 authenticate 函数先应用私钥对输出的加密字符串解密,取得明文后果,而后将其和内存中保留的正确的明码比对,再返回是否统一的查看后果。该类中保留的正确明码值和私钥都是平安敏感数据,authenticate 函数的实现也是平安敏感运算。它们都将在 TEE 中运行,以黑盒的模式提供给内部应用。从内部只能看到加密的输出数据和返回的断定后果,而无奈窥探到理论的运行过程和数据。
public class AuthenticationServiceImpl implements AuthenticationService {
private String pwd = "somePwd"; // assume it's got at runtime.
@Override
public boolean authenticate(String inputPwd) {String decryptedInputPwd = decrypt(inputPwd);
return pwd.equals(decryptedInputPwd);
}
private static String decrypt(String inputPwd) {return inputPwd; // assume it's decrypted with private key}
}
(代码块 2 在 Enclave 模块定义秘密计算服务接口实现示例)
Host 模块应用秘密计算服务的代码示例如代码块 3 所示,从中能够看到对秘密计算服务 AuthenticationService 接口的应用和一般的 SPI 接口别无二致,仍然是加载服务、调用函数、依据后果执行不同的动作等过程。稍有区别的中央在于先要创立出秘密计算环境 Enclave 的实例,而后从中加载秘密计算服务实例,由此将秘密计算的服务实例和环境实例绑定,最初再销毁环境。这些秘密计算环境生命周期治理的 API 由 Teaclave Java 提供。从代码块 3 中可见,在 Host 模块中无需感知明码和私钥到底是什么,也不必理解认证的过程,只是将认证函数当作黑盒服务调用。
public class Main {public static void main(String[] args) throws Exception {Enclave enclave = EnclaveFactory.create();
Iterator<AuthenticationService> services = enclave.load(AuthenticationService.class);
String pwd = "encryptedPwd"; // assume this is an encrypted password
while (services.hasNext()) {AuthenticationService authenticationService = services.next();
if (authenticationService.authenticate(pwd)) {System.out.println("Passed");
} else {System.out.println("Rejected");
}
}
enclave.destroy();}
}
(代码块 3 从 Host 模块应用秘密计算服务示例)
以上三局部代码就形成了一个残缺的 Java 秘密计算利用。从开发的角度看起来与编写一个一般的 SPI 服务调用的利用根本一样,只须要专一于业务逻辑的开发即可,并不需要学习秘密计算底层的内容。因而 Teaclave Java 将 Java 秘密计算的开发门槛升高到了 0。
构建秘密计算利用
Teaclave Java 提供了一套残缺的构建工具链以反对上文所述的编程模型,用户只需输出几个简略的 maven 命令即可实现全副构建工作。构建工具链将非秘密代码和秘密代码别离编译为 Java bytecode 产物和可部署于 SGX 中的 native 库,以及主动生成实现秘密计算服务调用所需的所有的辅助代码。
图 4 展现了 Teaclave Java 的构建部署视图,次要包含三方面内容:
1)Host 和 Common 模块被编译为一般的 Java bytecode,部署在一般环境中执行。
2)Enclave 和它所应用到的 Common 模块中的内容被编译为 native 秘密库文件,部署在 SGX 硬件中执行。
3)从 Java bytecode 到 native code 之间并不能间接调用,而须要一些适配转换工作,包含:
- 服务代理:通过 J ava 的动静代理机制将 Host 模块中的秘密计算服务调用代理到理论的 native 函数上,并实现上下文环境的同步、服务参数和返回值的序列化反序列化等工作。
- JNI 层:Java 侧的 native 函数申明、native 侧的 JNI 函数申明和到秘密库函数的调用等辅助代码。
(图 4 Teaclave Java 部署视图)
这些适配转换调用的代码在构建中被主动生成,别离部署在一般环境和 SGX 中,在图 4 中它们被用蓝色标出。
构建过程中的重要一步是将秘密局部的 Java 代码编译为 native 代码的 Java 动态编译。
Java 动态编译
Java 程序本来须要在 JVM 上能力运行,然而 Java 动态编译技术能够将 Java 程序(包含 JDK 库依赖和三方库依赖)加上必要的运行时反对代码一起编译为 native 代码,而后间接运行。以此实现了 Java 程序无需 JVM 的轻量级运行。
Teaclave Java 采纳了目前最成熟的 Java 动态编译技术——Oracle 主导的开源我的项目 GraalVM 进行 Java 动态编译。GraalVM 首先对 Java 程序做可达性剖析,找到从程序入口开始的所有可能执行到的代码范畴,而后仅编译这些可达的代码,失去一个 native 制品(被称为 native image)。程序入口对于可执行程序来说是 main 函数,对于库文件来说是裸露的公共 API。具体到 Teaclave Java 场景,入口就是开发者定义的秘密计算服务函数,也就是 Enclave 模块中定义的秘密计算服务接口的实现函数。这些接口实现会用到三种依赖,Common 模块中的代码、某些 JDK 库以及其余 Java 三方库,然而只会用到这些依赖的局部代码,而非全副代码。GraalVM 就会将理论用到的代码剖析进去,与秘密计算服务的实现代码和 GraalVM 提供的运行时反对(被称为 Substrate VM)一起编译为 native image。然而 GraalVM 是面向通用场景和硬件平台的,所以 Teaclave Java 为其额定提供了针对 SGX 硬件平台的适配和秘密计算需要的优化。当咱们编译出 native image 后,会发现其具备了一些特地的性质:
- TCB 降落。GraalVM 仅编译从秘密计算服务入口可达的代码,因而与 Occlum 将 LibOS、JVM 和 Java 利用全副放入 TEE 的计划相比,TCB 大幅升高了。
- 安全性晋升。Native image 在运行时有本人的 native 内存堆,它与 Java 堆是互相隔离的,从 Java 利用中很难被拜访到(Java 通过 Unsafe 接口仍然能够拜访 native 内存,然而难度晋升很多)。而且 Java 动态编译去掉了 Java 的动静个性,只有在编译时通过显式配置的反射和动静类加载才会失效,其余运行时的动静行为是有效的。Log4j 破绽攻打在 native image 上自身就是有效的。因而 native image 能够被视作一个平安沙箱,即便没有 SGX 硬件环境,native image 相比 Java 程序也晋升了安全性。部署在 SGX 里之后,TEE 的安全性会更高,因为打消了 Java 动静个性对 TEE 安全性的威逼。
- 性能晋升。GraalVM 的 Java 动态编译对代码有相当程度的编译优化,其运行时性能大抵能够达到 JVM 的 C1 优化程度,再加上无需启动 JVM、没有类加载过程、没有解释执行、没有 JIT 耗费资源等等,在执行短小的工作时与 Java 程序相比能有 1 个数量级的性能晋升,内存也有大幅削减。
这些性质能够无效地晋升秘密程序的安全性,晋升了 Teaclave Java 的实用性。
04 Teaclave Java 技术评估
以上介绍了 Teaclave Java 提供的 Java 秘密计算编程模型和采纳的构建形式等技术问题,那么最终实现的成果如何呢?本文以 log4j 破绽攻打为例剖析 Teaclave Java 的性能有效性。
在 TCB 改良和运行时性能剖析方面,咱们筹备了如表格 1 所示的 10 个测试。前 4 个“app-”前缀的是咱们本人写的简略利用,将它们当作秘密程序,以各自的 main 入口当作一般程序。后 6 个“ct-”前缀的用例则采纳了驰名开源加密框架 BouncyCastle(https://www.bouncycastle.org/java.html)的单元测试,咱们提供了繁多入口调用这些测试,将测试入口当作一般程序,单元测试当作秘密程序。
测试用例 | 依赖次要三方库 | 形容 |
---|---|---|
app-print | \ | 打印一条音讯字符串 |
app-digest | BouncyCastle-full | 调用 BouncyCastle 计算 hash 值 |
app-rsa | BouncyCastle-full | 调用 BouncyCastle 进行 RSA 加密 |
app-sqlparser | Druid | 应用 Druid 进行 SQL 解析 |
ct-asn1 | BouncyCastle-core | BouncyCastle-core 的 asn1 子模块测试 |
ct-i18n | BouncyCastle-core | BouncyCastle-core 的 i18n 子模块测试 |
ct-util | BouncyCastle-core | BouncyCastle-core 的 util 子模块测试 |
ct-math | BouncyCastle-core | BouncyCastle-core 的 math 子模块测试 |
ct-pqc | BouncyCastle-core | BouncyCastle-core 的 pqc 子模块测试 |
ct-crypto | BouncyCastle-core | BouncyCastle-core 的 crypto 子模块测试 |
(表 1 / 测试用例形容)
Java 秘密计算框架则采纳了 OcclumJ 和 Teaclave Java 进行比照。OcclumJ 是咱们实现的一种介于 Occlum 和 Teaclave Java 之间的秘密计算模型,采纳 Teaclave Java 的模块化和秘密计算服务化的模型,然而不做 Java 动态编译,而是在 TEE 中以 Occlum 形式运行秘密计算服务。
性能有效性评估
图 5 给出了 log4j 破绽攻打的原理示意(a 子图)和 Teaclave Java 防备 log4j 破绽攻打的原理(b 子图)。对于一个一般的 Java 应用服务,它和客户端通过三个步骤交互。
1)客户端从服务端获取公钥。
2)客户端用公钥对音讯加密,而后将密文发送给服务端。
3)服务端从运行时内存中拿出私钥解密音讯,而后再解决音讯内容。假如服务端应用了 log4j-2.14.x 版本做日志记录,其中的破绽容许攻击者诱导 log4j 从近程服务器下载指定的歹意 class 文件(图 5- a 中的步骤 4、5、6),而后动静加载歹意类,从 Java 堆内存上获取到私钥(步骤 7)传给攻击者。
有了服务器的私钥,服务器和客户端之间的所有通信对于攻击者而言都如同明文了。
a. log4j 破绽攻打示意(图 5 / Java 秘密计算爱护利用免 受 Log4j 破绽攻打示意图)
b. 通过秘密计算免疫 log4j 破绽攻打示意(图 5 / Java 秘密计算爱护利用免 受 Log4j 破绽攻打示意图)
图 5-b 展现了 Teaclave Java 如何爱护利用服务端免受 log4j 破绽攻打的威逼。Teaclave Java 将利用的一般代码放在 REE 中,平安敏感的解密和私钥放在 TEE 中,客户端送来加密音讯会被 REE 中的代理服务转到 TEE 中进行解密。此时当攻击者发动 log4j 攻打时,因为 Log4j 部署在 REE 中,恶意代码也只能在 REE 中运行,而无奈拿到 TEE 内存上的私钥,攻打生效。如果秘密代码也应用了 log4j 记日志,导致 log4j 运行在 TEE 中运行会产生什么呢?此时 log4j 将攻击者恶意代码下载到了 TEE 中,然而因为 Teaclave Java 采纳了 Java 动态编译技术,恶意代码在编译时是未知的,不会被编译到 native image 中。而 Java 动态编译技术并不反对对 native image 中不存在的代码进行动静加载执行,所以即使歹意类被下载到了 TEE,也不会被执行。因而在这种场景下 Teaclave Java 反对的秘密计算仍然是平安的。然而如果采纳了 Occlum 计划,因为 TEE 中有了 JVM,就能够动静加载恶意代码并运行,攻打就会胜利。
再退一步,当在没有 SGX 硬件为 TEE 加密时,native image 仍然是一个 native 沙箱,歹意 Java 代码无奈轻易从 native 内存中拿到平安敏感内容。
TCB 评估
因为 Teaclave Java 不再须要 LibOS 和 JVM,秘密代码局部也是按需编译部署。OcclumJ 计划尽管采纳了分模块模型,然而并没有做动态剖析,因而只是模块级别的代码划分,尽管较 Occlum 齐全不划分有所改进,然而与 Teaclave Java 函数级的划分相比仍有相当大的差距。图 6 展现了 OcclumJ 和 Teaclave Java 放入 TEE 的二进制编译产物的大小比照。蓝条是 OcclumJ 的后果,橙条是 Teaclave Java 的后果,图中的 Lejacon 是 Teaclave Java 在论文中的代号。
(图 6 Occlum 和 T eaclave Java 计划的 TCB 比拟。Lejacon 是 Teaclave Java 在论文中的代号)
由图 6 中的比照数据可见,Teaclave Java 的编译后 TCB 大小仅为 Occlum 的大概 1 /20 到 1/10。思考到编译时 native 代码的收缩问题,两者理论的函数数量差距更大,所以 Teaclave Java 的 TCB 低于 Occlum 一个数量级,从而具备了更高的安全性。
运行时性能评估
因为 native image 会间接以 native 代码的模式运行,省去了包含 JVM 启动、类加载、解释执行等步骤的 Java 程序的冷启动过程,所以启动速度会十分快。如果要执行的秘密代码较少,会很快执行结束。然而 native image 的代码编译品质不如 JVM 的 C2,所以当程序执行的工夫足够长,Java 代码被 JIT 充沛编译后,native image 的运行时性能就会随着工夫的增长而与 Java 程序越来越靠近,而后被超过。所以 Teaclave Java 在小型利用的性能远优于 OcclumJ,然而在长时间执行的利用方面该劣势就会放大。
图 7 就展现出了这一特点。图中的蓝线是秘密代码局部采纳 OcclumJ 模型的执行工夫,黄线是采纳 Teaclave Java 模型的执行工夫,绿线是在一般环境中在一般 JVM 上间接运行的工夫。程序在 TEE 中运行的工夫要大于一般环境,次要因为减少了秘密环境的创立、秘密内存的调配等开销,咱们将其统称为秘密环境开销。黄线在执行工夫较短的场景中放弃了与绿线靠近的性能,阐明 Java 程序冷启动的开销与 native image 的秘密环境开销差不多能够相抵。当程序执行工夫较长时,冷启动开销被摊薄,然而秘密环境开销与 TEE 内存使用量成正比,所以黄线较绿线在最初三个测试用例上的回升线条更平缓。
图 8 给出了 OcclumJ 和 Teaclave Java 的运行时内存使用量比照。OcclumJ 的内存耗费包含 LibOS、JVM 和利用三局部,而 Teaclave Java 模型的内存耗费只有利用和 native image 中的轻量级运行时。更简化的构造为 Teaclave Java 模式的秘密计算带来了更少的内存耗费。
(图 7 OcclumJ 和 Teaclave Java 运行时性能比照图。Lejacon 是 Teaclave Java 在论文中的代号)
(图 8 / OcclumJ 与 Teaclave Java 的运行时内存耗费比照图。Lejacon 是 Teaclave Java 在论文中的代号)
05 总结
Teaclave Java 是一个应用简略、效果显著、性能良好的 Java 秘密计算解决方案,可能帮忙用户彻底解决爱护 Java 利用中的平安敏感内容和运算的问题。Teaclave Java 具备硬件宽容性,当具备 SGX 硬件环境时,能够使 Java 用户也能像其余 native 语言用户一样享受到秘密计算带来的最高等级运行时平安爱护;在短少秘密计算的硬件环境时,依然能够提供平安沙箱对秘密代码施行内存隔离,以防止平安敏感内容间接裸露。能够说,Teaclave Java 就是爱护 Java 利用中敏感数据和运算平安的标准答案。
Oracle 曾经把 GraalVM 的 Java 动态编译技术奉献给了 OpenJDK,预计在 JDK 21 会合入 OpenJDK 骨干。因而在将来 Teaclave Java 计划就能够取得 JDK 的原生反对。咱们也打算向 Java 社区提交对于减少秘密计算标准的文件,心愿能够将 Teaclave Java 的秘密计算模型回升为 Java 原生的秘密计算计划。
本技术发表的论文为:Xinyuan Miao, Ziyi Lin, Shaojun Wang, Lei Yu, Sanhong Li, Zihan Wang, Pengbo Nie, Yuting Chen, Beijun Shen, He Jiang. Lejacon: A Lightweight and Efficient Approach to Java Confidential Computing on SGX. ICSE 2023.
论文链接:https://ddst.sjtu.edu.cn/Management/Upload/[News]a845acae286b470bb55013c1b5e425e2/20232101456536725sSV.pdf
Teaclave Java 我的项目的源代码曾经奉献到了 Apache 社区,退出秘密计算框架 Teaclave 我的项目,目前正在开源孵化中。
我的项目链接:https://github.com/apache/incubator-teaclave-java-tee-sdk
龙蜥社区云原生秘密计算 SIG 主页:
https://openanolis.cn/sig/coco
—— 完 ——