Получение ошибки при создании предопределенного URL для SSE-C - PullRequest
0 голосов
/ 20 марта 2019

Я создал ключ клиента для шифрования на стороне сервера AWS S3 с помощью ключа клиента (SSE-C).

Я могу загрузить объект с помощью ключа. Но когда я генерирую предварительно назначенный URL-адрес с помощью AWS Java SDK, URL-адрес создается успешно, но когда я нажимаю этот URL-адрес, я получаю сообщение об ошибке ниже.

SignatureDoesNotMatch Рассчитанная нами подпись запроса не соответствует предоставленной вами подписи. Проверьте свой ключ и метод подписи.

import java.io.IOException;
import java.net.URI;
import java.net.URL;

import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.HttpMethod;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.Headers;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.SSEAlgorithm;
import com.amazonaws.services.s3.model.SSECustomerKey;
import com.amazonaws.util.Base64;
import com.amazonaws.util.Md5Utils;

public class GeneratePresignedURL {

	public GeneratePresignedURL() throws IOException {
		String bucketName = "abctest";
		String keyName = "testnew.mp4";

		try {
			SSECustomerKey SSE_KEY = new SSECustomerKey("KLgsVafKowMCfKDsbIh597CmMUSoPBn6QJ8OIGxAMBw=");

			ClientConfiguration cnf = new ClientConfiguration();
			cnf.withSignerOverride("AWSS3V4SignerType");
			AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withClientConfiguration(cnf)
					.withCredentials(new ProfileCredentialsProvider()).build();

			// Set the presigned URL to expire after one hour.
			java.util.Date expiration = new java.util.Date();
			long expTimeMillis = expiration.getTime();
			expTimeMillis += 1000 * 60 * 60;
			expiration.setTime(expTimeMillis);

			// Generate the presigned URL.
			System.out.println("Generating pre-signed URL.");
			GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName,
					keyName).withMethod(HttpMethod.PUT).withExpiration(expiration).withSSECustomerKey(SSE_KEY);

			generatePresignedUrlRequest.setSSECustomerKeyAlgorithm(SSEAlgorithm.AES256);

			URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);

			System.out.println("Pre-Signed URL: " + url.toExternalForm());
		} catch (AmazonServiceException e) {
			// The call was transmitted successfully, but Amazon S3 couldn't process
			// it, so it returned an error response.
			e.printStackTrace();
		} catch (SdkClientException e) {
			// Amazon S3 couldn't be contacted for a response, or the client
			// couldn't parse the response from Amazon S3.
			e.printStackTrace();
		}
	}

Я пытался следовать коду из https://aws.amazon.com/blogs/developer/generating-amazon-s3-pre-signed-urls-with-sse-c-part-5-finale/

У меня нет проблем с использованием предварительно подписанного URL для SSE S3, у меня проблема только с SSE-C

Я попытался установить шифрование по умолчанию и другие настройки, но безрезультатно. Любые указатели будут очень полезны.

Спасибо, AK

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Спасибо @ паван

Любой клиент, которому необходимо использовать SSE-C, должен иметь возможность отправки заголовков ниже.

enter image description here

При использовании предварительно назначенного URL-адреса для извлечения существующего объекта или извлечения только метаданных объекта нам необходимо предоставить все заголовки шифрования в вашем клиентском приложении.

  • Для шифрования на стороне сервера под управлением S3 или KMS мы можем сгенерировать предварительно заданный URL-адрес и напрямую вставить его в браузер или проигрыватель.

  • Однако это не относится к объектам SSE-C, поскольку в дополнение к предварительно назначенный URL, вы также должны включить заголовки HTTP, которые специфичные для объектов SSE-C. Таким образом, вы можете использовать предопределенный URL для объектов SSE-C только программно.

Загрузить:

Я выбрал управляемые ключи S3 вместо предоставленного клиентом клиентского ключа.

        FileInputStream fin = new FileInputStream(uploadFileName);

        byte fileContent[] = new byte[(int) uploadFileName.length()];

        // Reads up to certain bytes of data from this input stream into an array of
        // bytes.
        fin.read(fileContent);
        // create string from byte array

        // Specify server-side encryption.
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(fileContent.length);
        objectMetadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
        PutObjectRequest putRequest = new PutObjectRequest(bucketName, keyName,
                new ByteArrayInputStream(fileContent), objectMetadata);

        // Upload the object and check its encryption status.
        PutObjectResult putResult = s3Client.putObject(putRequest);
        System.out.println("Object \"" + keyName + "\" uploaded with SSE.");

GET Presigned URL:

    java.util.Date expiration = new java.util.Date();
    long expTimeMillis = expiration.getTime();
    expTimeMillis += 1000 * 60 * 60;
    expiration.setTime(expTimeMillis);

    System.out.println("Generating pre-signed URL.");
    GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, keyName)
            .withMethod(HttpMethod.GET).withExpiration(expiration);

    URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
    System.out.println("Pre-Signed URL: " + url.toURI());

Ссылка: https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html

0 голосов
/ 26 марта 2019

Вы не можете позвонить по предварительно подписанному URL напрямую через браузер

Вам необходимо передать заголовки в запросе

  1. х-АМЗ-серверный-шифрования клиента алгоритм

  2. х-АМЗ-серверный-шифрование клиент-ключ

  3. х-АМЗ-серверный -encryption -Клиент ключ-MD5

Пожалуйста, проверьте документ для получения дополнительной информации https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html

При использовании предварительно назначенного URL-адреса для загрузки нового объекта, извлечения существующего объекта или извлечения только метаданных объекта необходимо указать все заголовки шифрования в клиентском приложении.

Пожалуйста, проверьте пример кода, вызывающего подписанный URL через библиотеку Unirest https://github.com/pavanpawar4591/s3signurlwith-sse-c

public static void getPreSignedURL() throws URISyntaxException {
        java.util.Date expiration = new java.util.Date();
        long expTimeMillis = expiration.getTime();
        expTimeMillis += 1000 * 60 * 60;
        expiration.setTime(expTimeMillis);

        System.out.println("Generating pre-signed URL.");
        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, keyName)
                .withMethod(HttpMethod.GET).withExpiration(expiration).withSSECustomerKey(SSE_KEY);

        // generatePresignedUrlRequest.setContentType("video/mp4");
        generatePresignedUrlRequest.setSSECustomerKeyAlgorithm(SSEAlgorithm.AES256);

        URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);

        System.out.println("Pre-Signed URL: " + url.toURI() + " With key: " + SSE_KEY);

        System.out.println("------------------------------");
        //https://aws.amazon.com/blogs/developer/generating-amazon-s3-pre-signed-urls-with-sse-c-part-4/ 
        // refer to above doc
        try {
            HttpResponse<String> response = Unirest.get(url.toURI().toString())
                    .header(Headers.SERVER_SIDE_ENCRYPTION_CUSTOMER_ALGORITHM, SSEAlgorithm.AES256.getAlgorithm())
                    .header(Headers.SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY, Base64.encodeAsString(SECRET_KEY.getEncoded()))
                    .header(Headers.SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY_MD5,
                            Md5Utils.md5AsBase64(SECRET_KEY.getEncoded()))
                    .header("cache-control", "no-cache").header("postman-token", "d3453c38-1b59-a12e-fd97-dbe2150eadf5")
                    .asString();

            System.out.println(response.getStatus());
            System.out.println(response.getStatusText());
            System.out.println(response.getBody());
        } catch (UnirestException e) {

            e.printStackTrace();
        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...