Blog de Amazon Web Services (AWS)

Cómo integrar AWS KMS con JCE y generar una CSR

Por Lucas Lins, Arquitecto de Soluciones de AWS
João Paulo Aragão Pereira, Arquitecto de Soluciones de AWS

 

En la mayoría de los contextos de industrias, como los Servicios Financieros, se requieren operaciones que impliquen el uso de claves asimétricas para la firma digital y la verificación de documentos y archivos. En este proceso, generalmente se utilizan certificados digitales válidos que atestiguan la propiedad de estas claves asimétrica a una persona, entidad o sistema.

AWS Key Management Service (KMS) es un servicio que facilita la creación y gestión de claves criptográficas y el control de su uso en una amplia gama de servicios de AWS y sus aplicaciones. Además, es un servicio totalmente gestionadoy altamente disponible, siendo una excelente opción para satisfacer las necesidades mencionadas anteriormente. Sin embargo, hay dos características intrínsecas de AWS KMS que hacen de su uso un estímulo, en el contexto de firma y verificación, para el desarrollo del proveedor AWS KMS JCE (Java Cryptography Extension).

En primer lugar, los módulos de seguridad de hardware multitenant (HSM) utilizados en el almacén de claves KMS estándar son validados por un laboratorio de terceros bajo el estándar FIPS 140-2 en el nivel 2, y con el nivel 3 en varias categorías. Además, AWS KMS está diseñado para que nadie, incluidos los empleados de AWS, pueda recuperar claves de cliente y utilizarlas fuera del servicio. Es decir, la clave privada nunca sale de AWS KMS. Sin embargo, sin la clave privada, no es posible utilizar herramientas, como OpenSSL, para generar la solicitud de firma de certificados (CSR) y obtener un certificado digital válido.

Por último, AWS KMS sólo tiene acceso a través de la API, que puede facilitarse a través de los SDK de AWS y, para algunas operaciones, con AWS Encryption SDK. En este momento, cuando escribimos esta publicación de blog, AWS Encryption SDK solo admite claves simétricas, y no es posible utilizar claves asimétricas para el cifrado (cifrado/descifrado) o para iniciar sesión en AWS Encryption SDK.

Varios lenguajes de programación tienen un estándar para el uso de operaciones criptográficas. En el caso de Java, por ejemplo, es el JCA/JCE. Por lo tanto, el objetivo de este blog es presentar el desarrollo de una biblioteca llamada AWS KMS JCE Provider, con el fin de realizar la integración entre AWS KMS con JCE y generar una CSR, con claves asimétricas.

Pero primero, vale la pena destacar otras características de AWS KMS.

 

AWS KMS

  • Además de las características mencionadas anteriormente con respecto a AWS KMS, vale la pena señalar que el servicio tiene:
  • API amigable.
  • Soporte de rotación automática para algunos tipos de clave.
  • Imposibilidad de extraer claves privadas.
  • Control de acceso fino .
  • Integración con AWS CloudTrail para registrar todas las solicitudes de API, incluidas las acciones de administración y el uso de sus claves.
  • Operaciones CMK simétricas: representa una única clave de cifrado secreta de 256 bits que nunca deja AWS KMS descifrado. Para utilizar el CMK simétrico, se requiere una llamada de API a AWS KMS.
  • Operaciones asimétricas de CMK: Representa una clave pública y una clave privada matemáticamente relacionada que se pueden usar para cifrar y descifrar o para firmar y verificar, pero no ambas. La clave privada nunca deja AWS KMS descifrado. Puede utilizar la clave pública en AWS KMS llamando a las operaciones de la API de KMS de AWS o puede descargar la clave pública y utilizarla fuera de AWS KMS.
  • Operaciones de clave de cifrado simétrico: clave de cifrado simétrico que se puede utilizar para cifrar datos fuera de AWS KMS. Esta clave está protegida por un CMK simétrico en AWS KMS.
  • Operaciones con claves de cifrado asimétricas: un par de claves RSA o curvas elípticas (ECC) que consisten en una clave pública y una clave privada. Puede utilizar la clave pública fuera de AWS KMS para cifrar y descifrar datos, o para verificar firmas.
  • Bajo coste y no hay compromiso ni cargos iniciales para utilizar AWS KMS.

 

Cifrar y descifrar

Las operaciones de cifrado, descifrado y recifrado en la API KMS de AWS están diseñadas para cifrar y descifrar claves de datos. Utilizan una clave maestra de cliente KMS (CMK) de AWSen operaciones de cifrado y no pueden aceptar más de los valores de la tabla siguiente:

Tecla Algoritmo Tamaño máximo (bytes)
Simétrico SYMMETRIC_DEFAULT 4096
RSA 2048 asimétrico RSAES_OAEP_SHA_1 214
  RSAES_OAEP_SHA_256 190
RSA 3072 asimétrico RSAES_OAEP_SHA_1 342
  RSAES_OAEP_SHA_256 318
RSA 4096 asimétrico RSAES_OAEP_SHA_1 470
  RSAES_OAEP_SHA_256 446

Aunque puede utilizar claves en KMS para cifrar pequeñas cantidades de datos, como una contraseña o una clave RSA, no están diseñadas para cifrar datos de aplicaciones.

Aunque AWS KMS admite el envío de datos según la tabla anterior, para el cifrado simétrico el cifrado de sobres puede ofrecer importantes ventajas de rendimiento. Cuando encripta datos directamente con AWS KMS, es necesario transferirlos a través de la red. Elcifrado de sobres reduce la carga de red porque sólo la solicitud y entrega de la clave de datos que suele ser mucho más pequeña se transmiten a través de la red. La clave de datos se utiliza localmente en su aplicación de AWS o servicio de cifrado, evitando la necesidad de enviar todo el bloque de datos a AWS KMS y experimentar latencia de red.

Estas fueron las razones por las que no se desarrolló la parte de cifrado/descifrado para el proveedor AWS KMS JCE, sino únicamente las operaciones de firma y verificación.

 

AWS KMS JCE Provider

AWS KMS JCE Provider Software Library for Java es una implementación de proveedor para el marco de proveedores Sun Java Cryptography Extension (JCE) que se centra en el uso de claves asimétricas para firmar y verificar . Esto incluye implementaciones para interfaces y clases de motor en el estándar Java Cryptography Architecture (JCA). El código fuente está disponible en el repositorio aws-samples/aws-kms-jce  en GitHub.

Para utilizar AWS KMS JCE Provider, primero debe crear un CMK asimétrico en AWS KMS para la firma y verificación. Un CMK asimétrico representa un par de claves públicas y privadas relacionadas matemáticamente. Es posible dar la clave pública a cualquier persona, incluso si no es de confianza, pero manteniendo la clave privada confidencial.

AWS KMS admite dos tipos de CMK asimétricos para la firma y la verificación.

  • RSA CMK: un CMK con un par de claves RSA. KMS admite varios tamaños de clave para diferentes requisitos de seguridad.
  • CMK de curva elíptica (ECC): un CMK con un par de teclas de curva elíptica. KMS admite varias curvas de uso común.

Ambos tipos son compatibles con AWS KMS JCE Provider, así como con todas sus variaciones de tamaño y todos sus algoritmos de firma.

 

Inicialización del proveedor

Para utilizar AWS KMS JCE Provider, primero debe crear el proveedor. El proveedor requiere que se informe al cliente de KMS cuando se crea. Es de destacar que la creación del cliente puede y debe ser personalizada para cada caso.

KMSClient KMSClient = KMSClient.builder() .build ();
kmsProvider kmsProvider = nuevo kmsProvider (kmsClient);

Una vez creado el proveedor, es posible registrarlo.

Seguridad.AddProvider(KMSProvider);

Obtención de referencias clave

Puede obtener referencias clave de dos maneras:

  • A través de KeyFactory: KMSRSKeyFactoryKMSecKeyFactory
  • A través de KeyStore: Almacén de claves de KMS

La diferencia entre las dos formas mencionadas es que para usar KeyFactory es necesario ingresar el ID de clave y para usar KeyStore se usa el alias de clave. Es de destacar que KeyStore utiliza KeyFactory, es decir, desde el alias dado se recupera el ID de clave y luego se usa KeyFactory. Siempre priorice el uso de KeyFactory para un mejor rendimiento.

Para usar KeyFactory (KMsrsKeyFactory o KMSecKeyFactory) simplemente invoque sus métodos estáticos:

KMSecKeyFactory.getKeyPair (...);
KMSecKeyFactory.getPrivateKey (...);
kmSecKeyFactory.getPublicKey (...);
...
KmsrsKeyFactory.getKeyPair (...);
KmsrsKeyFactory.getPrivateKey (...);
kmsrsKeyFactory.getPublicKey (- ¿Qué?);

Para usar el KeyStore, necesita obtener el KeyStore a través del estándar JCE y arranquearlo.

KeyStore KeyStore = KeyStore.getInstance («KMS»);
KeyStore.load (null, null);
...
keystore.alias ();
keystore.containsias (...);
keystore.size ();
keystore.getKey (- ¿Qué?);

 

Firma y verificación

Para facilitar el uso de la biblioteca, se ha creado la enumeración KMSSigningAlgorithm que tiene la asignación para utilizar el algoritmo deseado de la siguiente manera:

Algoritmo de firma de KMS Algoritmo de firma Java
RSASSA_PSS_SHA_256 RSASSA-PSS/SHA256
RSASSA_PSS_SHA_384 RSASSA-PSS/SHA384
RSASSA_PSS_SHA_512 RSASSA-PSS/SHA512
RSASSA_PKCS1_V1_5_SHA_256 SHA256conRSA
RSASSA_PKCS1_V1_5_SHA_384 Sha384conRSA
RSASSA_PKCS1_V1_5_SHA_512 SHA512 con RSA
ECDSA_SHA_256 SHA256con ECDS
ECDSA_SHA_384 Sha384 con ECDS
ECDSA_SHA_512 SHA512 con ECDS

Para firmar y/o verificar necesita obtener Firma a través de JCE:

KMSSigningAlgorithm KMSSigningAlgorithm = KMSSigningAlgorithm.<X>;

Firma KMSSignature = signature.getInstance (kmsSigningAlgorithm.getAlgorithm ());

//signing...
kmsSignature.initSign (privateKey);
kmsSignature.update (message.getBytes ());
byte [] signatureBytes = kmsSignature.sign ();

//checking...
kmsSignature.initVerify (PublicKey);
kmsSignature.update (message.getBytes ());
boolean valid = kmsSignature.verify (signatureBytes);

 

Generación de solicitud de firma de certificados (CSR) y certificado autofirmado

Antes de generar la CSR, primero debe definir la información que estará presente en la CSR. Para este propósito, se utiliza CSRInfo.

csrInfo csrInfo = csrInfo.builder()
        .cn («... «) //Nombre común
        .or («... «) //Nombre del departamento/ Unidad organizativa
        .o («... «) //Nombre comercial/Organización
        .l («... «) //Ciudad/Ciudad
        .st («... «) //Provincia, Región, Condado o Estado
        .c («... «) //País
        .mail («... «) //Dirección de correo electrónico
        .build ();

Después de crear CSRInfo, puede generar la CSR:

String csr = CSRGenerator.generar(KeyPair, CSRInfo, KMSSigningAlgorithm);

Con la CSR generada, puede generar el certificado autofirmado (si es necesario):

int validity = 365; //In days
String crt = SelfSignedCrtGenerator.generar(KeyPair, csr, KMSSigningAlgorithm, validez);

A continuación se puede ver un ejemplo completo de generación de CSR y certificado autofirmado:

Ejemplo de clase

    pública {public static void main (String [] args) {
        KmsClient KmsClient = KmsClient.builder () .build ();
        Security.addProvider (nuevo KmsProvider (KmsClient));

        KeyPair = KmsSRKeyFactory.getKeyPair (kmsClient, keyIDs.sign_rr (sa);
        kmsSigningAlgorithm kmsSigningAlgorithm.rsassa_pkcs1_v1_5_sha_256;

        csrInfo = csrinfo.builder ()
                .cn («kms.aws.amazon.com»)
                .o («AWS») .o («Amazon») .l («Sao Paulo»)
                .l («Sao Paulo»)
                .l) .l («Sao Paulo»)
                .st (»; Sao Paulo»)
                .c («BR»)
                .mail (» kms@amazon.com «)
                .build ();

        System.out.println («Información CSR:» + csrinfo.toString ());
        System.out.println ();

        String csr = csrGenerator.generate (par de claves, csrinfo, KMSSigningAlgorithm);
        System.Out.Println («CSR:»);
        System.Out.Println (csr);

        String crt = SelfSignedCrtGenerator.generate (par de claves, csr, KmsSigningAlgorithm, 365);
        System.Out.Println («CRT:»);
        System.Out.Println TLN (crt);
    }

}

Costos y límites

Cada clave maestra del cliente (CMK) que cree en AWS KMS cuesta 1 USD/mes hasta que se elimina, independientemente del lugar en el que el servicio generó el material de clave subyacente, un almacén de claves personalizado o una importación.

AWS KMS ofrece un nivel gratuito de 20.000 solicitudes por mes, calculado en todas las regiones en las que el servicio está disponible. Las solicitudes de las API GeneratedAtaKeyPair y GeneratedAtaKeyPairWithoutPlainText, así como las solicitudes de API como Sign, Verify, Encrypt, Descrypt y GetPublicKey que hacen referencia a CMK asimétricos, se excluyen de la capa gratuita.

Cada solicitud de API para AWS KMS (fuera de la capa gratuita) cuesta, en la región de América del Sur (Sao Paulo):

  • 0,03 USD por 10.000 solicitudes
  • 0,03 USD por 10.000 solicitudes con claves RSA 2048
  • 0,10 USD por 10.000 solicitudes de ECC GeneratedAtaKeyPair
  • 0,15 $por 10.000 solicitudes asimétricas excepto RSA 2048
  • 12,00 $por 10.000 solicitudes RSA GeneratedAtaKeyPair

En cuanto a los umbrales, más específicamente en las operaciones que utilizan claves asimétricas, AWS KMS tiene límites de:

  • 500 requisciones/segundo (compartido) para CMK RSA
  • 300 requisciones/segundo (compartido) para CMK de curva elíptica (ECC)

Si es necesario, puede solicitar el aumento para satisfacer la necesidad de su caso de uso.

 

Conclusión

En esta publicación mostramos cómo utilizar la biblioteca de software desarrollada de AWS KMS JCE Provider para integrar AWS KMS con JCE y generar una CSR, para admitir la firma de documentos Java que requieren un certificado digital válido.

 

Este artículo fue traducido del Blog de AWS en Portugués.

 


Sobre los autores

Lucas Lins es arquitecto de soluciones en AWS, con más de 10 años de experiencia en arquitectura de software y desarrollo de soluciones que involucran sistemas empresariales y de misión crítica. Se centra en el segmento Enterprise, guiando y apoyando a los clientes en su viaje a la nube.

 

 

 

 

João Paulo Aragão Pereira es un arquitecto de soluciones de AWS, centrado en el sector de servicios financieros (LATAM) y sus principales temas: prevención y detección de fraudes, banca abierta, modernización de sistemas heredados, prueba de vida, sistemas de pago instantáneo. He estado trabajando con arquitecturas bancarias y de seguros por más de 15 años.