AWS Подпись 4 завершается ошибкой, только если в полезной нагрузке указаны специальные символы - PullRequest
0 голосов
/ 30 января 2020

У нас есть метод POST, представленный на шлюзе API с включенной подписью 4. AWS сигнатура 4 работает нормально, когда в поле «* 1010» нет специальных символов. Но всякий раз, когда в полезной нагрузке JSON есть поле с такими символами, как апостроф ('), кавычки ("), мы получаем следующую ошибку. Имеет ли это какое-то отношение к кодировке?

Рассчитанная нами подпись запроса не соответствует предоставленной вами подписи. Проверьте свой секретный ключ доступа AWS и метод подписи. Для получения подробной информации обратитесь к документации по обслуживанию. \ N \ nСтрока Canonical для этого запроса должна быть \ n'POST \ n

Ниже приведен фрагмент кода

    private String calculateStringToSign() {
        final String stringToSign = format(STRING_TO_SIGN_FORMAT,
                SCHEME,
                ALGORITHM,
                DATE_HEADER_FORMATTER.format(signingTime),
                getScope(),
                toHexString(sha256(getCanonicalRequest())));
        log.debug("String to sign is ["+stringToSign+"]");
        return stringToSign;
    }

    private String getCanonicalRequest() {
        final String canonicalString = format(CANONICAL_REQUEST_FORMAT,
                method,
                getCanonicalizedResourcePath(),
                getCanonicalizedQueryString(),
                getCanonicalizedHeaders(),
                getCanonicalizedHeaderNames(),
                getHashedBody());
        log.debug("Canonical String is: ["+canonicalString+"]");
        return canonicalString;
    }

    private String getHashedBody() {
        return toHexString(sha256(body)).toLowerCase();
    }

    public static byte[] sha256(String input) {
        return hash(input, "SHA-256");
    }

    private static byte[] hash(String input, String algorithm) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            md.update(input.getBytes(UTF_8));
            return md.digest();
        }
        catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            log.error("Unable to compute hash", e);
            throw new AWSEncryptionException(e);
        }
    }

    private String getCanonicalizedResourcePath() {
        Optional<String> path = ofNullable(url).map(URL::getPath);

        if(!path.isPresent() || isBlank(path.get())) {
            return "/";
        }

        String encodedPath = urlEncode(path.get());

        if (encodedPath.startsWith("/")) {
            return encodedPath;
        }
        else {
            return "/".concat(encodedPath);
        }
    }

   private String urlEncode(String value) {
        String encoded;

        try {
             encoded= URLEncoder.encode(value, UTF_8);
        }
        catch (UnsupportedEncodingException e) {
            log.error("Specified URL encoding is not supported", e);
            throw new AWSEncryptionException(e);
        }

        encoded = encoded.replace("%2F", "/");
        encoded = encoded.replace("%7E", "~");

        return encoded;
    }

    private String getCanonicalizedHeaderNames() {
        return headers.keySet().stream()
                .sorted(CASE_INSENSITIVE_ORDER)
                .map(String::toLowerCase)
                .collect(joining(";"));
    }

    private String getCanonicalizedHeaders() {
        return headers.keySet().stream()
                .sorted(CASE_INSENSITIVE_ORDER)
                .map(key -> {
                    String formattedKey = key.toLowerCase().replaceAll("\\s+", " ");
                    String formattedValue = headers.get(key).stream()
                            .filter(Objects::nonNull)
                            .flatMap(value -> of(value.split("\\R+")))
                            .map(StringUtils::trimWhitespace)
                            .map(value -> value.replaceAll("\\s+", " "))
                            .collect(joining(","));

                    return formattedKey + ":" + formattedValue;
                })
                .collect(joining("\n"));
    }

    private String getCanonicalizedQueryString() {
        return queryParameters.entrySet().stream()
                .flatMap(entry -> entry.getValue().stream()
                        .map(value -> new AbstractMap.SimpleEntry<>(
                                urlEncode(entry.getKey()), urlEncode(value)
                        ))
                        .collect(toList())
                        .stream()
                )
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .sorted()
                .collect(joining("&"));
    }


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