¿Cómo garantizar la seguridad de la aplicación Java? Aquí viene la respuesta estándar | Dragon Lizard Technology

Texto / Ziyi Lin, mantenedor SIG de computación confidencial nativa en la nube

"¿Cómo puedo mantener seguras las contraseñas en la memoria del programa Java?"

Si ha tenido problemas similares y ha encontrado algunas respuestas incompletas pero inútiles en Internet, significa que usted es un interesado en los problemas de seguridad del programa Java.

La respuesta estándar a esta pregunta es la Tecnología informática confidencial de Java, que introduce la Tecnología informática confidencial en el mundo Java y aporta una mejora significativa a la seguridad de los programas Java. En base a esto, el SIG de computación confidencial nativa en la nube de la comunidad Dragon Lizard ha lanzado la tecnología de implementación específica de la computación confidencial de Java: Teaclave Java TEE SDK , en lo sucesivo denominado Teaclave Java. Esta tecnología tiene las siguientes ventajas significativas:

  • Seguridad en todos los escenarios . Cuando el usuario tiene soporte de hardware de computación confidencial, Teaclave Java puede realizar la computación confiable de Java con el más alto nivel de seguridad ; cuando el usuario no tiene el hardware relevante, degenera en computación confiable en el nivel de aislamiento de la zona de pruebas de seguridad , que también puede proteger de manera efectiva la seguridad del usuario. datos sensibles y Seguridad del proceso informático.

  • Fácil de desarrollar y construir . El modelo de programación Java puro basado en SPI, la construcción con un solo clic, reduce al mínimo el umbral del desarrollo y la construcción de computación confidencial de Java.

Teaclave Java se ha verificado en escenarios internos de nivel empresarial y es de código abierto en la comunidad de Apache. El documento que describe esta tecnología fue publicado en ICSE 2023 (https://conf.researchr.org/home/icse-2023), la principal reunión de ingeniería de software, por Cloud Native Confidential Computing SIG de Dragon Lizard Community, en cooperación con la Universidad Jiaotong de Shanghai y la Universidad Tecnológica de Dalian, y ganó el premio ACM SIGSOFT Outstanding Paper Award de esta conferencia. Esta es la primera vez desde 2020 que Dragon Lizard Community Cloud Native Confidential Computing SIG, Shanghai Jiao Tong University y Dalian University of Technology han ganado este honor.

01  La esencia del problema

La esencia de este problema es cómo usar datos confidenciales de manera segura en un entorno de tiempo de ejecución riesgoso. Cuando desciframos la contraseña en tiempo de ejecución, la contraseña existirá en la memoria en forma de texto sin formato, es decir, en el montón de Java, como se muestra en la mitad izquierda de la Figura 1. Si el sistema es atacado, como el notorio ataque de vulnerabilidad log4j en 2021, el contenido del montón de Java puede ser robado. Incluso si no es atacado, es posible filtrar activamente información confidencial al realizar un volcado de almacenamiento dinámico para el diagnóstico de rendimiento. Por lo tanto, exponer información confidencial de seguridad, como contraseñas, a entornos operativos comunes es muy riesgoso .

(Ilustración esquemática de la protección de contraseña de Java simple en la Figura 1)

Una forma de protección es acortar el tiempo de almacenamiento de las contraseñas de texto sin formato en la memoria tanto como sea posible, a fin de acortar la ventana de tiempo para la exposición de información confidencial . Como se muestra en la mitad derecha de la Figura 1, después de usar la contraseña, se eliminará de la memoria a tiempo, lo que será más seguro que antes. Debido a que la contraseña es información de texto, se guardará con la clase de cadena java.lang.String. La cadena de Java es un tipo inmutable y el contenido no se puede cambiar después de la creación, por lo que no hay una API que pueda restablecer el contenido. Para destruir la contraseña, la única forma de borrar el contenido de la contraseña del montón de Java es borrar el contenido de la matriz que almacena el contenido de caracteres dentro de la clase String a través de la reflexión. Es inútil establecer directamente la cadena de contraseña en nulo, lo que solo establece el puntero de la variable String en nulo y no tiene ningún efecto sobre los datos de contraseña en el montón de Java. Otra forma es almacenar la contraseña en una matriz de caracteres en lugar de la clase String , para que no tenga que llamar a la reflexión y hacer que la destrucción sea más conveniente. Otro método es usar una matriz de bytes para guardar la contraseña, porque el texto sin formato es una codificación de caracteres en lugar de caracteres legibles por humanos, por lo que será más difícil de entender para las personas.

Estas son las soluciones que se pueden encontrar en Internet hoy en día, y este artículo se refiere a ellas como esquemas de protección de contraseña Java "ingenuos" . Porque estos esquemas solo acortan el tiempo de vida de la contraseña de texto sin formato en el montón de Java y realmente no protegen la contraseña de texto sin formato. Además, la palabra "oportuno" tiene una gran flexibilidad y es posible que los desarrolladores no puedan juzgar con precisión cuándo es oportuno.

Un caso más típico es el famoso problema de vulnerabilidad log4j ( https://nvd.nist.gov/vuln/detail/CVE-2021-44228 ). Un atacante puede explotar la vulnerabilidad de log4j 2.14 para cargar un archivo de clase malicioso en el servidor y ejecutarlo a través del mecanismo de carga de clase dinámica de Java, robando así la clave privada del servidor almacenada en el montón de Java. Con la clave privada, todo el contenido de la comunicación entre el servidor y el cliente es como texto sin formato para el atacante.

En los dos ejemplos anteriores, las contraseñas y las claves que deben protegerse en tiempo de ejecución son datos sensibles a la seguridad. En escenarios reales, el alcance de la protección no se limita a los datos confidenciales, sino que también puede extenderse a los procesos informáticos . Por ejemplo, en escenarios de autenticación y autenticación, es necesario garantizar que el proceso de autenticación sea creíble y que los atacantes no puedan manipularlo. Otro ejemplo es cuando los usuarios de servicios en la nube implementan sus propios algoritmos en la nube, aunque los productos implementados se pueden cifrar para proteger la seguridad de la transmisión y el almacenamiento, y los proveedores de la nube brindan una protección de seguridad inexpugnable contra ataques externos, los usuarios aún se preocupan por la computación en la nube. el fabricante espía el proceso informático del usuario en tiempo de ejecución y si existe la posibilidad de auto-robo.

Se puede ver que la protección de datos y cálculos sensibles a la seguridad en aplicaciones Java no es una demanda lejana, sino una demanda con un significado práctico urgente . Para los proveedores de computación en la nube, la caja negra que convence a los usuarios de que sus datos y cálculos confidenciales son invisibles para los proveedores de la nube también tiene un valor comercial importante.

02  Estado de la informática confidencial de Java

La protección de datos confidenciales en tiempo de ejecución no es un tema nuevo, sino que forma parte de una tecnología que ha evolucionado durante más de 20 años: la informática confidencial. La informática confidencial es una tecnología que proporciona aislamiento del sistema a nivel de hardware para garantizar la seguridad de los datos y la seguridad del funcionamiento del programa. La computación confidencial divide el entorno de ejecución en Rich Execution Environment (REE) y Trusted Execution Environment (Trusted Execution Environment, TEE), y cree que REE y TEE deben estar aislados entre sí, y TEE necesita ser encriptado por hardware para garantizar que el el mundo exterior no puede conocer el contenido. El contenido sensible a la seguridad debe ejecutarse en el TEE y el resto del contenido debe ejecutarse en el REE.

Este mecanismo se propuso ya en 1999, pero la primera tecnología de cifrado de hardware tiene capacidades limitadas, solo hardware TPM (Trusted Platform Module) que admite la ejecución de programas de cifrado y descifrado. En 2008, Arm publicó el documento técnico TrustZone para respaldar las tareas informáticas confidenciales de propósito general en la plataforma Arm. En 2015, Intel también lanzó un dispositivo de hardware con un chip SGX (Software Guard Extension) que admite el cifrado de aplicaciones de uso general. En 2021, SGX se actualizará a SGX2, que puede admitir 1T de memoria y tener un mayor rendimiento.

El concepto central de la informática confidencial es proporcionar un área segura para que los programas sensibles a la seguridad se ejecuten en un entorno de tiempo de ejecución que corre el riesgo de ser atacado, y darse cuenta de la seguridad y confiabilidad de los datos y programas sensibles a la seguridad en todo el proceso de transmisión, almacenamiento y computación. En la actualidad, la informática confidencial tiene una amplia gama de aplicaciones y amplias perspectivas en seguridad de la privacidad, cadena de bloques, informática multipartita, IoT y dispositivos perimetrales, así como dispositivos informáticos personales.

Parece que la tecnología informática confidencial es la respuesta estándar para resolver el problema de la seguridad del programa Java, entonces, ¿podemos aplicar la tecnología informática confidencial en las aplicaciones Java?

Occlum: coloca la JVM y el monolito de la aplicación en el TEE

SGX, TrustZone, etc. proporcionan la base de hardware para la informática confidencial de uso general, y los controladores y SDK de código abierto como Intel y Microsoft proporcionan la base de software para la informática confidencial de uso general. Sobre la base de estos fundamentos de hardware y software, los desarrolladores ya pueden utilizar la computación confidencial en aplicaciones de software. Pero la computación confidencial no es compatible con las aplicaciones Java, porque solo los programas nativos pueden ejecutarse en TEE, por lo que los programas Java no pueden ejecutarse directamente en TEE. Para ejecutar un programa Java en el TEE, primero debe iniciar una JVM en el TEE y luego ejecutar el programa Java en la JVM . Entonces, ¿es posible ejecutar una JVM dentro de un TEE? La respuesta es sí, eso es Occlum, y su principio se muestra en la Figura 2.

Occlum es una capa de LibOS entre el SDK subyacente del TEE y la JVM. Como sistema operativo, admite el funcionamiento de las JVM ordinarias en el TEE . El usuario implementa todo el programa Java, incluido el código confidencial en el TEE, que es ejecutado por la JVM compatible con Occlum. La mitad derecha de la Figura 2 muestra la estructura de implementación, donde la aplicación amarilla representa la aplicación Java completa y su biblioteca de tres partes requerida, y el círculo rojo representa el código de confianza. Las aplicaciones son lanzadas por un lanzador en REE, generalmente solo una pequeña herramienta de línea de comandos. Esta solución tiene buena compatibilidad y los usuarios básicamente no necesitan modificar el código original para obtener soporte informático confidencial. Pero la desventaja también es obvia: demasiado código en TEE causará dos problemas:

1. Disminución de la seguridad . Es posible que no haya muchos programas confiables que deban ejecutarse en TEE, pero esta solución necesita colocar todos los programas Java, bibliotecas de tres partes, JVM y LibOS en TEE, lo que resulta en una TCB (Base de computación confiable) demasiado grande, la seguridad no es ideal. TCB es un indicador importante para medir la seguridad en el campo de la seguridad, en referencia a la cantidad de código confiable. Cuanto más grande sea el TCB, más códigos pueden tener riesgos de seguridad y peor será la seguridad del programa, por lo que cuanto más pequeño sea el TCB, mejor . Tome el ataque log4j como ejemplo, Occlum aún no es inmune a él. Debido a que la biblioteca log4j y el código confidencial no están separados en diferentes entornos de ejecución, sino que se implementan en el TEE, los archivos de clase maliciosos cargados por el atacante también se ubicarán en el TEE y aún se puede acceder a la clave privada desde la memoria. .

2. Degradación del rendimiento . El hardware de TEE no es hardware de uso general y hay una degradación del rendimiento en comparación con REE, por lo que poner toda la aplicación en TEE conducirá a la degradación del rendimiento de toda la aplicación. Sin embargo, la demanda original del usuario es solo un cifrado parcial, y la degradación general del rendimiento causada por el cifrado parcial aumentará el costo de aplicar la computación confidencial. Aunque los usuarios generales pueden aceptar cierta degradación del rendimiento por motivos de seguridad, es difícil aceptar la degradación adicional del rendimiento provocada por el cifrado excesivo.

(Figura 2 Diagrama esquemático del principio Oclum)

En resumen, aunque el esquema Occlum tiene la ventaja de ser simple y fácil de implementar, sus deficiencias en términos de seguridad y rendimiento son los principales obstáculos para su aplicación práctica.

03  Teaclave Java TEE SDK: coloque solo código confiable en TEE

Debido a que el esquema de soporte de la JVM y todas las aplicaciones en el TEE ejecutará demasiado código en el TEE, lo que resultará en una disminución de la seguridad y el rendimiento, es difícil ponerlo en práctica. ¿Puedes cambiar la forma de pensar y solo poner código de confianza en el TEE? Teniendo en cuenta que solo se puede ejecutar código nativo en TEE, ¿es posible compilar directamente código confiable de código Java en código nativo y ponerlo en TEE para ejecutarlo? La respuesta es sí, este es el protagonista de este artículo, Teaclave Java TEE SDK, en adelante denominado Teaclave Java.

Teaclave Java es un marco de desarrollo de computación confidencial de Java y una cadena de herramientas de construcción desarrollada por el equipo de JVM, que puede realizar rápidamente el desarrollo y la construcción de aplicaciones de computación confidencial de Java en una sola parada. Dando un paso atrás, incluso si el usuario no tiene un entorno de hardware que admita la informática confidencial, Teaclave Java también puede lograr el aislamiento de la zona de pruebas de seguridad, lo que garantiza de manera efectiva la seguridad en tiempo de ejecución de los datos y programas confidenciales.

Las características técnicas clave de Teaclave Java son:

1) Separación de módulos y servicio de cómputo confidencial, como se muestra en la Figura 3.

2) API de gestión del ciclo de vida del servicio informático confidencial conciso y completo.

3) Java compila estáticamente secretos.

4) Oculte los detalles de implementación y genere automáticamente todos los códigos auxiliares.

Con el apoyo de estas tecnologías, Teaclave Java puede convertir las llamadas de servicio entre módulos Java de módulos ordinarios a módulos confidenciales en llamadas de función de módulos ordinarios a bibliotecas nativas confidenciales, como se muestra en la Figura 4.

Separación de módulos, servicio informático confidencial

Teaclave Java divide el código de la aplicación en tres módulos, Host, Enclave y Common . Host es un programa no sensible a la seguridad común, Enclave es un programa sensible a la seguridad y Common es el código común utilizado por los dos primeros. Este método de división de módulos es para permitir que los desarrolladores perciban la distinción de seguridad del código, y el segundo es para facilitar el uso de diferentes cadenas de herramientas para diferentes módulos durante la construcción.

Host y Enclave están desacoplados y solo pueden interactuar a través del mecanismo SPI (Interfaz de proveedor de servicios) de Java y no se pueden llamar directamente. La implementación de la computación confidencial se empaqueta como un servicio en el módulo Enclave, y su declaración de interfaz se define en el módulo Común y se marca con la anotación @EnclaveService. Cuando un programa en el Host necesita usar una determinada tarea informática confidencial, primero puede cargar la instancia del servicio y luego llamar a la función correspondiente. La relación organizacional de esta estructura se muestra en la Figura 3.

(Figura 3 Vista de desarrollo de Teaclave Java)

Por ejemplo, podemos declarar una interfaz de servicio informático confidencial que se muestra en el bloque de código 1 en Común, que proporciona una API y una función de autenticación para verificar si la contraseña cifrada es válida. Esta función acepta una contraseña cifrada pasada por el usuario y devuelve el resultado de autenticación de la contraseña.

@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);
}

El bloque de código 1 define un ejemplo de declaración de interfaz de servicio informático confidencial en el módulo común

La implementación específica de la interfaz AuthenticationService se define en la clase AuthenticationServiceImpl del módulo Enclave, como se muestra en el bloque de código 2. La función de autenticación de esta clase primero usa la clave privada para descifrar la cadena cifrada de entrada para obtener el resultado del texto sin formato, luego lo compara con la contraseña correcta almacenada en la memoria y luego devuelve el resultado de verificar si es consistente. El valor de contraseña correcto y la clave privada almacenada en esta clase son todos datos sensibles a la seguridad, y la implementación de la función de autenticación también es una operación sensible a la seguridad. Todos se ejecutarán en el TEE, disponibles como cajas negras para uso externo. Solo los datos de entrada cifrados y el resultado del juicio devuelto se pueden ver desde el exterior, pero el proceso de operación real y los datos no se pueden ver.

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
    }
}

El bloque de código 2 define el ejemplo de implementación de la interfaz del servicio informático confidencial en el módulo Enclave

El ejemplo de código del módulo Host que utiliza el servicio de computación confidencial se muestra en el bloque de código 3, desde el cual podemos ver que el uso de la interfaz AuthenticationService del servicio de computación confidencial es el mismo que el de la interfaz SPI ordinaria, y todavía está cargando servicios, llamando a funciones, y realizando diferentes acciones según los resultados, etc. del proceso. La pequeña diferencia es que primero se debe crear una instancia del entorno informático confidencial Enclave, y luego se carga la instancia del servicio informático confidencial, vinculando así la instancia del servicio informático confidencial y la instancia del entorno, y finalmente se destruye el entorno. Teaclave Java proporciona la API para la gestión del ciclo de vida de estos entornos informáticos confidenciales. Se puede ver en el bloque de código 3 que en el módulo Host, no es necesario saber cuál es la contraseña y la clave privada, ni comprender el proceso de autenticación, sino llamar a la función de autenticación como un servicio de caja negra.

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();
    }
}

Bloque de código 3 Ejemplo de uso del Servicio de Cómputo Confidencial desde el módulo Host

Las tres partes de código anteriores constituyen una aplicación informática confidencial completa de Java. Desde la perspectiva del desarrollo, parece básicamente lo mismo que escribir una aplicación llamada por un servicio SPI ordinario. Solo necesita concentrarse en el desarrollo de la lógica comercial y no necesita aprender el contenido subyacente de la informática confidencial. Por lo tanto, Teaclave Java reduce a cero el umbral de desarrollo de la informática confidencial de Java.

Cree aplicaciones informáticas confidenciales

Teaclave Java proporciona un conjunto completo de cadenas de herramientas de construcción para admitir el modelo de programación descrito anteriormente, y los usuarios solo necesitan ingresar algunos comandos simples de Maven para completar todas las tareas de construcción. La cadena de herramientas de construcción compila códigos no confidenciales y códigos confidenciales en productos de código de bytes de Java y bibliotecas nativas que se pueden implementar en SGX, y genera automáticamente todos los códigos auxiliares necesarios para completar las llamadas de servicios informáticos confidenciales.

La Figura 4 muestra la vista de implementación de compilación de Teaclave Java, que incluye principalmente tres aspectos:

1) Los módulos Host y Common se compilan en código de bytes Java común, se implementan y ejecutan en entornos comunes.

2) El contenido de Enclave y los módulos comunes que utiliza se compilan en archivos de biblioteca confidenciales nativos y se implementan en el hardware SGX para su ejecución.

3) No se puede llamar directamente desde el código de bytes de Java al código nativo, pero requiere un trabajo de adaptación y conversión, que incluye:

  • Proxy de servicio: a través del mecanismo de proxy dinámico de Java, la llamada de servicio informático confidencial en el módulo Host se delega a la función nativa real y se completa la sincronización del contexto, la serialización y deserialización de los parámetros de servicio y los valores de retorno.

  • Capa JNI: declaración de función nativa en el lado de Java, declaración de función JNI en el lado nativo y códigos auxiliares como llamadas a funciones de biblioteca confidencial.

(Figura 4 Vista de implementación de Teaclave Java)

Los códigos llamados por estas transformaciones de adaptación se generan automáticamente durante la construcción y se implementan en el entorno normal y SGX respectivamente y están marcados en azul en la Figura 4.

Un paso importante en el proceso de compilación es la compilación estática de Java, que compila la parte confidencial del código Java en código nativo.

Compilación estática de Java

Los programas de Java originalmente deben ejecutarse en la JVM, pero la tecnología de compilación estática de Java puede compilar programas de Java (incluidas las dependencias de la biblioteca JDK y las dependencias de la biblioteca de terceros) junto con los códigos de soporte de tiempo de ejecución necesarios en código nativo y luego ejecutarlos directamente. De esta forma, se realiza la ejecución ligera de programas Java sin JVM.

Teaclave Java utiliza la tecnología de compilación estática de Java más avanzada: el proyecto de código abierto GraalVM para la compilación estática de Java liderado por Oracle . GraalVM primero analiza la accesibilidad del programa Java, encuentra todos los rangos de código posibles que se pueden ejecutar desde la entrada del programa y luego solo compila estos códigos accesibles para obtener un artefacto nativo (llamado imagen nativa). La entrada del programa es la función principal del programa ejecutable y la API pública expuesta para el archivo de la biblioteca. Específico para el escenario Java de Teaclave, el punto de entrada es la función del servicio informático confidencial definida por el desarrollador, es decir, la función de implementación de la interfaz del servicio informático confidencial definida en el módulo Enclave. Estas implementaciones de interfaz usarán tres dependencias, el código en el módulo común, algunas bibliotecas JDK y otras bibliotecas de terceros de Java, pero solo se usarán algunos de los códigos de estas dependencias, no todos los códigos. GraalVM analizará el código realmente utilizado y lo compilará en una imagen nativa junto con el código de implementación del servicio informático confidencial y el soporte de tiempo de ejecución proporcionado por GraalVM (llamado Substrate VM). Sin embargo, GraalVM está orientado a escenarios generales y plataformas de hardware, por lo que Teaclave Java le brinda adicionalmente la adaptación de la plataforma de hardware SGX y la optimización de los requerimientos de computación confidencial. Cuando compilamos la imagen nativa, encontraremos que tiene algunas propiedades especiales:

  • Gotas de TCB . GraalVM solo compila el código al que se puede acceder desde el portal de Confidential Computing Service, por lo que el TCB se reduce significativamente en comparación con la solución de Occlum de colocar las aplicaciones LibOS, JVM y Java en el TEE.

  • Seguridad mejorada . La imagen nativa tiene su propio montón de memoria nativa en tiempo de ejecución, que está aislado del montón de Java y es difícil acceder a él desde las aplicaciones Java (Java todavía puede acceder a la memoria nativa a través de la interfaz Unsafe, pero es mucho más difícil). Además, la compilación estática de Java elimina las características dinámicas de Java. Solo tendrán efecto la reflexión y la carga dinámica de clases que se configuran explícitamente en tiempo de compilación, y otros comportamientos dinámicos en tiempo de ejecución no son válidos. El ataque de vulnerabilidad Log4j no es válido en la propia imagen nativa. Por lo tanto, la imagen nativa puede considerarse como un entorno limitado de seguridad Incluso sin el entorno de hardware SGX, la imagen nativa mejora la seguridad en comparación con los programas Java. Después de implementarse en SGX, la seguridad de TEE será mayor, porque se eliminará la amenaza de las características dinámicas de Java para la seguridad de TEE.

  • Mejoras de rendimiento . La compilación estática de Java de GraalVM tiene un grado considerable de optimización de compilación para el código, y su rendimiento en tiempo de ejecución puede alcanzar aproximadamente el nivel de optimización C1 de la JVM. Además, no es necesario iniciar la JVM, no hay proceso de carga de clases, no hay ejecución de interpretación. , sin consumo de recursos JIT, etc. En comparación con los programas Java, puede tener una mejora de rendimiento de orden de magnitud al ejecutar tareas cortas, y la memoria también se reduce considerablemente.

Estas propiedades pueden mejorar efectivamente la seguridad de los programas confidenciales y mejorar la viabilidad de Teaclave Java.

04  Evaluación de la tecnología Java de Teaclave

Lo anterior presenta los problemas técnicos, como el modelo de programación de computación confidencial de Java proporcionado por Teaclave Java y el método de construcción adoptado, entonces, ¿cuál es el efecto de implementación final? Este documento toma el ataque de la vulnerabilidad log4j como ejemplo para analizar la efectividad funcional de Teaclave Java.

En términos de mejora de TCB y análisis de rendimiento del tiempo de ejecución, preparamos 10 pruebas como se muestra en la Tabla 1. Los primeros cuatro prefijos "app-" son aplicaciones simples escritas por nosotros mismos. Los tratamos como programas confidenciales y usamos sus entradas principales como programas ordinarios. Los últimos seis casos de uso con el prefijo "ct-" utilizan las pruebas unitarias del famoso marco de cifrado de código abierto BouncyCastle (https://www.bouncycastle.org/java.html) . Proporcionamos una única entrada para llamar a estas pruebas y use la entrada de prueba como un programa ordinario, la prueba unitaria como un programa confidencial.

caso de prueba Confíe en la biblioteca principal de tres partes describir
aplicación de impresión \ imprimir una cadena de mensaje
app-resumen BouncyCastle-full Llame a BouncyCastle para calcular el valor hash
app-rsa BouncyCastle-full Llame a BouncyCastle para el cifrado RSA
aplicación-sqlparser druida Análisis de SQL con Druid
ct-asn1 BouncyCastle-núcleo Prueba del submódulo asn1 de BouncyCastle-core
ct-i18n BouncyCastle-núcleo Pruebas del submódulo i18n de BouncyCastle-core
ct-util BouncyCastle-núcleo Pruebas de submódulos útiles de BouncyCastle-core
ct-matemáticas BouncyCastle-núcleo La prueba del submódulo matemático de BouncyCastle-core
ct-pqc BouncyCastle-núcleo La prueba del submódulo pqc de BouncyCastle-core
ct-crypto BouncyCastle-núcleo Prueba de submódulo criptográfico de BouncyCastle-core

(Tabla 1 / Descripción del caso de prueba)

El marco informático confidencial para Java utiliza OcclumJ y Teaclave Java para comparar. OcclumJ es un modelo de computación confidencial entre Occlum y Teaclave Java implementado por nosotros. Adopta el modelo de servicio de computación confidencial y modularización de Teaclave Java, pero no compila Java estáticamente, sino que se ejecuta en modo Occlum en TEE. Confidential Computing Services.

Evaluación de la eficacia funcional

La Figura 5 muestra el principio del ataque de vulnerabilidad log4j (subfigura a) y el principio de Teaclave Java que previene el ataque de vulnerabilidad log4j (subfigura b). Para un servicio de aplicación Java ordinario, interactúa con el cliente a través de tres pasos.

1) El cliente obtiene la clave pública del servidor.

2) El cliente cifra el mensaje con la clave pública y luego envía el texto cifrado al servidor.

3) El servidor extrae la clave privada de la memoria de tiempo de ejecución para descifrar el mensaje y luego procesa el contenido del mensaje. Suponiendo que el servidor utiliza la versión log4j-2.14.x para el registro, la vulnerabilidad permite al atacante inducir a log4j a descargar el archivo de clase malicioso especificado del servidor remoto (pasos 4, 5, 6 en la Figura 5-a), y luego cargar dinámicamente La clase maliciosa obtiene la clave privada de la memoria del montón de Java (paso 7) y se la pasa al atacante.

Con la clave privada del servidor, todas las comunicaciones entre el servidor y el cliente aparecen como texto sin formato para el atacante.

A. Ilustración de ataque de vulnerabilidad log4j

b. Inmunidad a los ataques de vulnerabilidad log4j a través de la informática confidencial

(Figura 5 / Diagrama esquemático de las aplicaciones de protección informática confidencial de Java de los ataques de vulnerabilidad de Log4j)

La Figura 5-b muestra cómo Teaclave Java protege el servidor de aplicaciones de los ataques de vulnerabilidad log4j. Teaclave Java coloca el código común de la aplicación en el REE y coloca el descifrado sensible a la seguridad y la clave privada en el TEE. El mensaje cifrado enviado por el cliente será reenviado al TEE por el servicio proxy en el REE para su descifrado. En este momento, cuando el atacante lanza un ataque log4j, debido a que Log4j se implementa en el REE, el código malicioso solo puede ejecutarse en el REE, pero no puede obtener la clave privada en la memoria del TEE y el ataque falla. ¿Qué sucede si el código confidencial también usa log4j para el registro, lo que provoca que log4j se ejecute en el TEE? En ese momento, log4j descargó el código malicioso del atacante en el TEE, pero debido a que Teaclave Java usa la tecnología de compilación estática de Java, el código malicioso se desconoce en el momento de la compilación y no se compilará en la imagen nativa. La tecnología de compilación estática de Java no admite la carga dinámica y la ejecución de código que no existe en la imagen nativa, por lo que incluso si la clase maliciosa se descarga en el TEE, no se ejecutará. Por lo tanto, en este escenario, la informática confidencial compatible con Teaclave Java sigue siendo segura. Sin embargo, si se adopta la solución de Occlum, dado que hay una JVM en el TEE, el código malicioso puede cargarse y ejecutarse dinámicamente, y el ataque tendrá éxito.

Dando un paso atrás, cuando no hay hardware SGX para cifrar el TEE, la imagen nativa sigue siendo un espacio aislado nativo y el código Java malicioso no puede obtener fácilmente contenido sensible a la seguridad de la memoria nativa.

Evaluación TCB

Dado que Teaclave Java ya no necesita LibOS ni JVM, la parte del código confidencial también se compila y se implementa bajo demanda. Aunque el esquema de OcclumJ adopta el modelo de submódulo, no hace análisis estático, por lo que solo divide el código a nivel de módulo.Aunque es mejorado en comparación con la no división de Occlum, todavía tiene una brecha considerable en comparación con Teaclave. División de nivel de función de Java. . La figura 6 muestra una comparación del tamaño de las compilaciones binarias Java de OcclumJ y Teaclave colocadas en el TEE. La barra azul es el resultado de OcclumJ, la barra naranja es el resultado de Teaclave Java y Lejacon en la figura es el nombre en clave de Teaclave Java en el documento.

(Figura 6 Comparación de TCB de las soluciones Java de Occlum y Teaclave. Lejacon es el nombre en clave de Teaclave Java en el documento)

Se puede ver a partir de los datos comparativos en la Figura 6 que el tamaño de TCB compilado de Teaclave Java es solo alrededor de 1/20 a 1/10 del de Occlum . Teniendo en cuenta la expansión del código nativo en tiempo de compilación, la brecha entre el número real de funciones entre los dos es mayor, por lo que el TCB de Teaclave Java es un orden de magnitud inferior al de Occlum, que tiene mayor seguridad.

evaluación del rendimiento en tiempo de ejecución

Debido a que la imagen nativa se ejecutará directamente en forma de código nativo, se omite el proceso de inicio en frío del programa Java, incluido el inicio de JVM, la carga de clases, la interpretación y los pasos de ejecución, por lo que la velocidad de inicio será muy rápida. Si hay un código menos confidencial para ejecutar, se ejecutará rápidamente. Sin embargo, la calidad de compilación del código de la imagen nativa no es tan buena como la del C2 de JVM, por lo que cuando el tiempo de ejecución del programa es lo suficientemente largo y JIT compila completamente el código Java, el rendimiento del tiempo de ejecución de la imagen nativa será más cercano. y más cercano al del programa Java a medida que pasa el tiempo, y luego superado. Por lo tanto, el rendimiento de Teaclave Java es mucho mejor que OcclumJ en aplicaciones pequeñas, pero la ventaja se reducirá en aplicaciones de ejecución prolongada.

La Figura 7 demuestra esta característica. La línea azul en la figura es el tiempo de ejecución de la parte del código confidencial que usa el modelo OcclumJ, la línea amarilla es el tiempo de ejecución que usa el modelo Teaclave Java y la línea verde es el tiempo que se ejecuta directamente en una JVM normal en un entorno normal. . El tiempo de ejecución del programa en el TEE es más largo que en el entorno normal, principalmente porque aumentan la creación del entorno confidencial, la asignación de memoria confidencial y otros gastos generales, a los que nos referimos colectivamente como los gastos generales del entorno confidencial. . La línea amarilla mantiene un rendimiento cercano al de la línea verde en una escena con un tiempo de ejecución corto, lo que indica que la sobrecarga del inicio en frío del programa Java casi puede compensar la sobrecarga del entorno confidencial de la imagen nativa. Cuando el tiempo de ejecución del programa es largo, la sobrecarga del arranque en frío se diluye, pero la sobrecarga del entorno secreto es proporcional al uso de la memoria TEE, por lo que la línea amarilla es más pronunciada que la línea verde en los últimos tres casos de prueba.

La Figura 8 muestra la comparación del uso de la memoria en tiempo de ejecución de OcclumJ y Teaclave Java. El consumo de memoria de OcclumJ incluye tres partes: LibOS, JVM y la aplicación, mientras que el consumo de memoria del modelo Java de Teaclave es solo la aplicación y el tiempo de ejecución ligero en la imagen nativa. Una estructura más simplificada conduce a un menor consumo de memoria para la computación confidencial en el modo Java de Teaclave.

(Figura 7 Gráfico de comparación de rendimiento de tiempo de ejecución de OcclumJ y Teaclave Java. Lejacon es el nombre en clave de Teaclave Java en el documento)

(Figura 8 / Comparación del consumo de memoria en tiempo de ejecución entre OcclumJ y Teaclave Java. Lejacon es el nombre en clave de TeaclumJava en el documento)

05  Resumen

Teaclave Java es una solución informática confidencial de Java que es fácil de usar, eficaz y de buen rendimiento. Puede ayudar a los usuarios a resolver por completo el problema de proteger el contenido y la informática sensibles a la seguridad en las aplicaciones Java. Teaclave Java tiene tolerancia de hardware. Cuando está equipado con el entorno de hardware SGX, los usuarios de Java pueden disfrutar del más alto nivel de protección de seguridad en tiempo de ejecución que brinda la informática confidencial como otros usuarios de idiomas nativos ; Se puede proporcionar un entorno limitado de seguridad para implementar el aislamiento de memoria para códigos confidenciales para evitar exposición de contenido sensible a la seguridad. Se puede decir que Teaclave Java es la respuesta estándar para proteger datos confidenciales y seguridad informática en aplicaciones Java.

Oracle ha contribuido con la tecnología de compilación estática Java de GraalVM a OpenJDK, que se espera que se integre en la red troncal de OpenJDK en JDK 21. Por lo tanto, la solución Teaclave Java podrá obtener soporte nativo del JDK en el futuro. También planeamos enviar un documento sobre cómo agregar especificaciones informáticas confidenciales a la comunidad de Java, con la esperanza de actualizar el modelo informático confidencial de Teaclave Java a una solución informática confidencial nativa de Java.

Los artículos publicados por esta tecnología son: 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.

Enlace de papel:

https://ddst.sjtu.edu.cn/Management/Upload/[Noticias]a845acae286b470bb55013c1b5e425e2/20232101456536725sSV.pdf

El código fuente del proyecto Teaclave Java se contribuyó a la comunidad Apache, se unió al marco informático confidencial del proyecto Teaclave y actualmente se encuentra en incubación de código abierto.

Enlace del proyecto: https://github.com/apache/incubator-teaclave-java-tee-sdk

Página de inicio de Dragon Lizard Community Cloud Native Confidential Computing SIG:

https://openanolis.cn/sig/coco

-- encima--

Supongo que te gusta

Origin blog.csdn.net/weixin_60347558/article/details/130017368
Recomendado
Clasificación