Protección de la integridad de los datos con sumas de comprobación - AWS SDK for Java 2.x

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Protección de la integridad de los datos con sumas de comprobación

Amazon Simple Storage Service (Amazon S3) permite especificar una suma de comprobación al cargar un objeto. Cuando se especifica una suma de comprobación, esta se almacena con el objeto y se puede validar cuando se descarga el objeto.

Las sumas de comprobación proporcionan un nivel adicional de integridad de los datos al transferir archivos. Con las sumas de comprobación, puede comprobar la coherencia de datos verificando que el archivo recibido coincide con el archivo original. Para obtener más información sobre las sumas de comprobación con Amazon S3, consulte la Guía del usuario de Amazon Simple Storage Service, que incluye los algoritmos compatibles.

Puede elegir el algoritmo que mejor se adapte a sus necesidades y dejar que el SDK calcule la suma de comprobación. También puede especificar un valor de suma de comprobación precalculada mediante uno de los algoritmos compatibles.

nota

A partir de la versión 2.30.0 de AWS SDK for Java 2.x, el SDK proporciona protecciones de integridad predeterminadas mediante el cálculo automático de una suma de comprobación de CRC32 para las cargas. El SDK calcula esta suma de comprobación si no proporciona un valor de suma de comprobación precalculado o si no especifica un algoritmo que el SDK deba usar para calcular una suma de comprobación.

El SDK también proporciona una configuración global para protecciones de integridad de datos que puede establecer de forma externa y sobre la que puede obtener más información en la Guía de referencia de las herramientas y los SDK de AWS.

Analizaremos las sumas de comprobación en dos fases de solicitud: carga del objeto y descarga del objeto.

Cargar un objeto

Al cargar un objeto con el método putObject y proporcionar un algoritmo de suma de comprobación, el SDK calcula la suma de comprobación del algoritmo especificado.

El siguiente fragmento de código muestra una solicitud para cargar un objeto con una suma de comprobación SHA256. Cuando el SDK envía la solicitud, calcula la suma de comprobación SHA256 y carga el objeto. Amazon S3 valida la integridad del contenido calculando la suma de comprobación y comparándola con la suma de comprobación proporcionada por el SDK. A continuación, Amazon S3 almacena la suma de comprobación con el objeto.

public void putObjectWithChecksum() { s3Client.putObject(b -> b .bucket(bucketName) .key(key) .checksumAlgorithm(ChecksumAlgorithm.SHA256), RequestBody.fromString("This is a test")); }

Si no proporciona un algoritmo de suma de comprobación con la solicitud, el comportamiento de la suma de comprobación varía en función de la versión del SDK que utilice, tal y como se muestra en la siguiente tabla.

Comportamiento de la suma de comprobación cuando no se proporciona ningún algoritmo de suma de comprobación

Versión del SDK de Java Comportamiento de la suma de comprobación
anterior a la versión 2.30.0 El SDK no calcula automáticamente una suma de comprobación basada en CRC ni la proporciona en la solicitud.
2.30.0 o posteriores

El SDK usa el algoritmo CRC32 para calcular la suma de comprobación y la proporciona en la solicitud. Amazon S3 valida la integridad de la transferencia calculando su propia suma de comprobación CRC32 y la compara con la suma de comprobación proporcionada por el SDK. Si las sumas de comprobación coinciden, la suma de comprobación se guarda con el objeto.

Utilizar un valor de suma de comprobación calculado previamente

Un valor de suma de comprobación precalculado proporcionado con la solicitud desactiva el cálculo automático por parte del SDK y utiliza el valor proporcionado en su lugar.

En el siguiente ejemplo se muestra una solicitud con una suma de comprobación SHA256 precalculada.

public void putObjectWithPrecalculatedChecksum(String filePath) { String checksum = calculateChecksum(filePath, "SHA-256"); s3Client.putObject((b -> b .bucket(bucketName) .key(key) .checksumSHA256(checksum)), RequestBody.fromFile(Paths.get(filePath))); }

Si Amazon S3 determina que el valor de la suma de comprobación es incorrecto para el algoritmo especificado, el servicio devuelve una respuesta de error.

Cargas multiparte

También puede utilizar sumas de comprobación en las cargas multiparte.

El SDK de Java 2.x ofrece dos opciones para usar sumas de comprobación con cargas multiparte. La primera opción usa S3TransferManager.

En el siguiente ejemplo de administrador de transferencias se especifica el algoritmo SHA1 para la carga.

public void multipartUploadWithChecksumTm(String filePath) { S3TransferManager transferManager = S3TransferManager.create(); UploadFileRequest uploadFileRequest = UploadFileRequest.builder() .putObjectRequest(b -> b .bucket(bucketName) .key(key) .checksumAlgorithm(ChecksumAlgorithm.SHA1)) .source(Paths.get(filePath)) .build(); FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest); fileUpload.completionFuture().join(); transferManager.close(); }

Si no proporciona un algoritmo de suma de comprobación al utilizar el administrador de transferencias para cargas, el SDK calcula automáticamente una suma de comprobación basada en el algoritmo CRC32. El SDK realiza este cálculo para todas las versiones del SDK.

La segunda opción usa la API S3Client (o la API S3AsyncClient) para llevar a cabo la carga multiparte. Si especifica una suma de comprobación con este método, debe especificar el algoritmo que se utilizará al iniciar la carga. También debe especificar el algoritmo para cada solicitud de parte y proporcionar la suma de comprobación calculada para cada parte una vez cargada.

public void multipartUploadWithChecksumS3Client(String filePath) { ChecksumAlgorithm algorithm = ChecksumAlgorithm.CRC32; // Initiate the multipart upload. CreateMultipartUploadResponse createMultipartUploadResponse = s3Client.createMultipartUpload(b -> b .bucket(bucketName) .key(key) .checksumAlgorithm(algorithm)); // Checksum specified on initiation. String uploadId = createMultipartUploadResponse.uploadId(); // Upload the parts of the file. int partNumber = 1; List<CompletedPart> completedParts = new ArrayList<>(); ByteBuffer bb = ByteBuffer.allocate(1024 * 1024 * 5); // 5 MB byte buffer try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) { long fileSize = file.length(); long position = 0; while (position < fileSize) { file.seek(position); long read = file.getChannel().read(bb); bb.flip(); // Swap position and limit before reading from the buffer. UploadPartRequest uploadPartRequest = UploadPartRequest.builder() .bucket(bucketName) .key(key) .uploadId(uploadId) .checksumAlgorithm(algorithm) // Checksum specified on each part. .partNumber(partNumber) .build(); UploadPartResponse partResponse = s3Client.uploadPart( uploadPartRequest, RequestBody.fromByteBuffer(bb)); CompletedPart part = CompletedPart.builder() .partNumber(partNumber) .checksumCRC32(partResponse.checksumCRC32()) // Provide the calculated checksum. .eTag(partResponse.eTag()) .build(); completedParts.add(part); bb.clear(); position += read; partNumber++; } } catch (IOException e) { System.err.println(e.getMessage()); } // Complete the multipart upload. s3Client.completeMultipartUpload(b -> b .bucket(bucketName) .key(key) .uploadId(uploadId) .multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build())); }

El código completo de los ejemplos y las pruebas está disponible en el repositorio de ejemplos de código de GitHub.

Descargar un objeto

Cuando se utiliza el método getObject para descargar un objeto, el SDK valida automáticamente la suma de comprobación cuando el método checksumMode del compilador de GetObjectRequest se establece como ChecksumMode.ENABLED.

La solicitud del siguiente fragmento indica al SDK que valide la suma de comprobación de la respuesta calculándola y comparando los valores.

public GetObjectResponse getObjectWithChecksum() { return s3Client.getObject(b -> b .bucket(bucketName) .key(key) .checksumMode(ChecksumMode.ENABLED)) .response(); }
nota

Si el objeto no se cargó con una suma de comprobación, no se realizará ninguna validación.

Otras opciones de cálculo de la suma de comprobación

nota

Para verificar la integridad de los datos transmitidos e identificar errores de transmisión, recomendamos a los usuarios que mantengan la configuración predeterminada del SDK para las opciones de cálculo de la suma de comprobación. De forma predeterminada, el SDK agrega esta importante comprobación a muchas operaciones de S3, incluidas PutObject y GetObject.

Sin embargo, si el uso de Amazon S3 requiere una validación mínima de la suma de comprobación, puede deshabilitar muchas comprobaciones cambiando los ajustes de configuración predeterminados.

Deshabilite el cálculo automático de la suma de comprobación a menos que sea necesario

Puede deshabilitar el cálculo automático de la suma de comprobación mediante el SDK para las operaciones que lo admiten, por ejemplo, PutObject y GetObject. Sin embargo, algunas operaciones de S3 requieren un cálculo de la suma de comprobación; no se puede deshabilitar el cálculo de la suma de comprobación para estas operaciones.

El SDK proporciona ajustes independientes para el cálculo de una suma de comprobación de la carga útil de una solicitud y de la carga útil de una respuesta.

En la siguiente lista se describen las configuraciones que puede usar para minimizar los cálculos de la suma de comprobación en los distintos ámbitos.

  • Ámbito de todas las aplicaciones: al cambiar la configuración de las variables de entorno o de un perfil en los archivos AWS, config y credentials compartidos, todas las aplicaciones pueden utilizar esta configuración. Esta configuración afecta a todos los clientes de servicio de todas las aplicaciones del AWS SDK, a menos que se anule en el ámbito de la aplicación o del cliente de servicio.

    • Adición de la configuración a un perfil:

      [default] request_checksum_calculation = WHEN_REQUIRED response_checksum_validation = WHEN_REQUIRED
    • Adición de variables de entorno:

      AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED
  • Ámbito actual de la aplicación: puede establecer la propiedad del sistema Java en aws.requestChecksumCalculation a WHEN_REQUIRED para limitar el cálculo de la suma de comprobación. La propiedad del sistema correspondiente para respuestas es aws.responseChecksumValidation.

    Esta configuración afecta a todos los clientes de servicio del SDK en la aplicación, a menos que se anulen durante la creación del cliente de servicio.

    Defina la propiedad del sistema en el inicio de la aplicación:

    import software.amazon.awssdk.core.SdkSystemSetting; import software.amazon.awssdk.core.checksums.RequestChecksumCalculation; import software.amazon.awssdk.core.checksums.ResponseChecksumValidation; import software.amazon.awssdk.services.s3.S3Client; class DemoClass { public static void main(String[] args) { System.setProperty(SdkSystemSetting.AWS_REQUEST_CHECKSUM_CALCULATION.property(), // Resolves to "aws.requestChecksumCalculation". "WHEN_REQUIRED"); System.setProperty(SdkSystemSetting.AWS_RESPONSE_CHECKSUM_VALIDATION.property(), // Resolves to "aws.responseChecksumValidation". "WHEN_REQUIRED"); S3Client s3Client = S3Client.builder().build(); // Use s3Client. } }
  • Ámbito de cliente de servicio individual de S3: puede configurar un cliente de servicio individual de S3 para calcular la cantidad mínima de sumas de comprobación mediante métodos de creación:

    import software.amazon.awssdk.core.checksums.RequestChecksumCalculation; import software.amazon.awssdk.services.s3.S3Client; public class RequiredChecksums { public static void main(String[] args) { S3Client s3 = S3Client.builder() .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED) .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED) .build(); // Use s3Client. } // ... }

Utilice LegacyMd5Plugin para simplificar la compatibilidad con MD5

Junto con el lanzamiento del comportamiento de suma de comprobación de CRC32 en la versión 2.30.0, el SDK dejó de calcular las sumas de comprobación MD5 en las operaciones requeridas.

Si necesita un comportamiento de suma de comprobación MD5 heredado para las operaciones de S3, puede utilizar el LegacyMd5Plugin, que se publicó con la versión 2.31.32 del SDK.

El LegacyMd5Plugin resulta especialmente útil cuando se necesita mantener la compatibilidad con aplicaciones que dependen del comportamiento heredado de la suma de comprobación MD5, especialmente cuando se trabaja con proveedores de almacenamiento de terceros compatibles con S3, como los que se utilizan con los conectores de sistemas de archivos de S3A (Apache Spark, Iceberg).

Para usar el LegacyMd5Plugin, agréguelo al compilador de clientes de S3:

// For synchronous S3 client. S3Client s3Client = S3Client.builder() .addPlugin(LegacyMd5Plugin.create()) .build(); // For asynchronous S3 client. S3AsyncClient asyncClient = S3AsyncClient.builder() .addPlugin(LegacyMd5Plugin.create()) .build();

Si desea agregar sumas de comprobación MD5 a las operaciones que requieren sumas de comprobación y quiere omitir la adición de las sumas de comprobación predeterminadas del SDK para operaciones que admiten sumas de comprobación pero no son obligatorias, puede habilitar las opciones requestChecksumCalculation y responseChecksumValidation de ClientBuilder como WHEN_REQUIRED. De este modo se agregarán sumas de comprobación predeterminadas del SDK solo a las operaciones que requieran sumas de comprobación:

// Use the `LegacyMd5Plugin` with `requestChecksumCalculation` and `responseChecksumValidation` set to WHEN_REQUIRED. S3AsyncClient asyncClient = S3AsyncClient.builder() .addPlugin(LegacyMd5Plugin.create()) .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED) .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED) .build();

Esta configuración resulta especialmente útil cuando se trabaja con sistemas de almacenamiento de terceros compatibles con S3 que pueden no ser totalmente compatibles con los algoritmos de suma de comprobación más recientes, pero que requieren sumas de comprobación MD5 para determinadas operaciones.