Проверка правильности ключа всегда не проходит

Валидатор проверочного ключа всегда возвращает неверный проверочный ключ.

Я имею в виду https://github.com/Microsoft/Office-Online-Test-Tools-and-Documentation/blob/master/samples/java/ProofKeyTester.java

@GET
@Path("/{file_id}")
@Produces(APPLICATION_JSON)
public Response checkFileInfo(@PathParam("file_id") String fileId, @QueryParam("access_token") String accessToken, @Context HttpHeaders httpHeaders, @Context HttpServletRequest request) {
    try {
        String proof = httpHeaders.getRequestHeader("X-WOPI-Proof") != null ? httpHeaders.getRequestHeader("X-WOPI-Proof").get(0) : null;
        String proofOld = httpHeaders.getRequestHeader("X-WOPI-ProofOld") != null ? httpHeaders.getRequestHeader("X-WOPI-ProofOld").get(0) : null;
        String wopiTimeStamp = httpHeaders.getRequestHeader("X-WOPI-TimeStamp") != null ? httpHeaders.getRequestHeader("X-WOPI-TimeStamp").get(0) : null;
        String urlSrc = request.getRequestURL().toString();
        String replacedStr = HTTP.matcher(urlSrc).replaceAll("https");
        validateProofKey(proof, proofOld, wopiTimeStamp, replacedStr, accessToken);

}

private void validateProofKey(String proof, String proofOld, String timeStamp, String urlSrc, String accessToken) throws Exception {
    LOGGER.info("verifying proof key");
    ProofKeyManager proofKeyManager = getBean(ProofKeyManager.class);
    String url = urlSrc + (urlSrc.contains(".wopitest") ? "?TESTCATEGORY=OFFICEONLINE&ACCESS_TOKEN=" : "?ACCESS_TOKEN=") + accessToken;
    byte[] expectedProof = proofKeyManager.getExpectedProofBytes(url, accessToken, timeStamp);
    WopiDiscovery wopiDiscovery = getBean(WopiDiscoveryProcessService.class).getWopiDiscoveryData();
    String modulus = wopiDiscovery.getProofKey().getModulus();
    String exponent = wopiDiscovery.getProofKey().getExponent();
    String oldModulus = wopiDiscovery.getProofKey().getOldmodulus();
    String oldExponent = wopiDiscovery.getProofKey().getOldexponent();
    boolean validScenario = proofKeyManager.verifyProofKey(modulus, exponent, proof, expectedProof);
    boolean validScenarioWithOld = proofKeyManager.verifyProofKey(modulus, exponent, proofOld, expectedProof);
    boolean oldPK = proofKeyManager.verifyProofKey(oldModulus, oldExponent, proof, expectedProof);
    if (proofKeyManager.verifyProofKey(modulus, exponent, proof, expectedProof) || proofKeyManager.verifyProofKey(modulus, exponent, proofOld, expectedProof) || proofKeyManager.verifyProofKey(oldModulus, oldExponent, proof, expectedProof)) {
        LOGGER.info("proof key is valid");
    } else {
        LOGGER.error("proof key is not valid");
        //throw new Exception("Invalid proof key");
    }

}

Если запрос сгенерирован офисом онлайн, в нем должно быть указано "ключ подтверждения действителен". но даже в действительном случае это регистрирует "проверочный ключ не действителен"

1 ответ

Я не могу прямо ответить на этот вопрос, но недавно у меня была такая же проблема с реализацией проверки ключа доказательства в PHP. Было довольно много вещей, которые я делал неправильно в результате того, что либо неправильно читал документы, либо в документах что-то не указывалось. В итоге решил это, переведя примеры тестов в связанном репозитории github на PHP. Две основные проблемы, которые у меня были:

  1. Создание открытого ключа из модуля и показателя степени Заданные модуль и показатель степени в процессе обнаружения представляют собой двоичный код в кодировке base64, который представляет собой большое десятичное число. Вам нужно декодировать base64, затем преобразовать в шестнадцатеричный, а затем преобразовать в десятичный. В зависимости от вашего языка/системы вам, вероятно, понадобится некоторая библиотека-оболочка вокруг десятичной дроби, потому что она может быть слишком большой, чтобы поместиться в intили же double.

  2. Кодирование чисел для ожидаемого доказательства Вам необходимо получить длину маркера доступа и URL-адреса, а затем закодировать их. Я использовал функцию php pack('J', $number)для этого.

Вам также нужно закодировать метку времени, для чего я использовал pack('N', $number), вычислите его длину, а затем закодируйте длину, используя описанный выше метод.

В конце концов, это было много проб и ошибок. Я клонировал примерный репозиторий и запустил тесты проверки python , по пути распечатав разные значения (например, модуль, экспоненту, длину токена доступа, URL-адрес, отметку времени и то, что они кодируют) и сравнил это с тем, что выводил мой код .

Не идеальный ответ, но это был сложный процесс, поэтому, надеюсь, он может указать людям правильное направление.

Другие вопросы по тегам