Nano Hash - криптовалюты, майнинг, программирование

Создание токена SAS на Java для загрузки файла в контейнер хранилища данных Azure

Попытка создать токен SAS для доступа к определенным файлам в учетной записи хранения. Я использую перечисленные здесь методы:

https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token

Теперь у меня проблема в том, что я не могу, хоть убей, заставить работать строку sasToken. Если я сгенерирую токен через портал (подпись общего доступа в учетной записи хранения), я могу получить доступ к этим файлам через URL-адрес с предоставленным токеном.

Однако мне еще предстоит сгенерировать токен SAS программно через Java, используя методы, которые я привел выше. Я думаю, что моя проблема - это StringToSign, который шифруется. Я следовал этому примеру при построении строки для шифрования:

https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas

Все мои усилия привели к:

<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>

or

<AuthenticationErrorDetail>Signature did not match. String to sign used was <insert string details here>

Глядя на сгенерированный порталом sasToken, который у меня работает:

? sv = 09.11.2017 & ss = f & srt = o & sp = r & se = 2018-12-06T22: 15: 20Z & st = 2018-12-06T14: 15: 20Z & spr = https & sig =% 2Bi1TWv5D80U% 2BoaIeoBh1wjaO1p4xVFx4zwiszt% 2F

Кажется, мне нужна такая строка:

            String stringToSign = accountName + "\n" +
                "r\n" +
                "f\n" +
                "o\n" +
                URLEncoder.encode(start, "UTF-8") + "\n" +
                URLEncoder.encode(expiry, "UTF-8") + "\n" +
                "\n" +
                "https\n" +
                azureApiVersion;

Где accountName - это имя учетной записи хранения из Azure, а start / expiry - строки начала и окончания срока действия (т.е. 2018-12-06T22: 15: 20Z), а azureApiVersion - «2017-11-09».

Затем я пытаюсь вернуть токен после построения строки следующим образом:

        String signature = getHMAC256(key, stringToSign);
        sasToken = "sv=" + azureApiVersion +
                "&ss=f" +
                "&srt=o" +
                "&sp=r" +
                "&se=" +URLEncoder.encode(expiry, "UTF-8") +
                "&st=" + URLEncoder.encode(start, "UTF-8") +
                "&spr=https" +
                "&sig=" + URLEncoder.encode(signature, "UTF-8");

Я пробовал кодирование URL-адресов, а не кодирование URL-адресов дат начала / истечения срока действия, на всякий случай, когда это все испортило. Что мне не хватает?


  • Какое значение ключа вы используете? Это строка, полученная с портала, или массив байтов, полученный в результате декодирования строки ключа учетной записи с помощью base64? 06.12.2018
  • Значение моего ключа является одним из ключей доступа в учетной записи хранения в Azure. 06.12.2018
  • Я считаю, что проблема в вашем getHMAC256 методе. Я нашел код для него, и он просто получает байты из строкового значения. На самом деле вам нужно будет декодировать строку ключа base64 и использовать этот массив байтов в этом методе. 06.12.2018
  • Хорошо, я попытался изменить используемый базовый метод getHMAC256: SecretKeySpec secret_key = new SecretKeySpec (Base64.getDecoder (). Decode (key), HmacSHA256); И, к сожалению, получил обратно Подпись не совпадала. Используемая строка для подписи была ‹и т. Д. и т. д. и т. д. ›сообщение. 06.12.2018
  • @seanDematic У меня такая же ошибка? Удалось ли вам это решить? 31.07.2020

Ответы:


1

Три момента, которые нужно исправить

  1. getHMAC256 проблема метода, упомянутая @Gaurav

  2. Не кодируйте expiry и start в stringToSign, иначе подпись не совпадет. Поскольку закодированная часть URL-адреса будет декодирована службой хранилища Azure для вычисления ожидаемой подписи.

  3. В stringToSign пропустите один \n после azureApiVersion.

Вот полный образец.

 public static void GetFileSAS(){

    String accountName = "accountName";
    String key = "accountKey";
    String resourceUrl = "https://"+accountName+".file.core.windows.net/fileShare/fileName";

    String start = "startTime";
    String expiry = "expiry";
    String azureApiVersion = "2017-11-09";

    String stringToSign = accountName + "\n" +
                "r\n" +
                "f\n" +
                "o\n" +
                start + "\n" +
                expiry + "\n" +
                "\n" +
                "https\n" +
                azureApiVersion+"\n";

    String signature = getHMAC256(key, stringToSign);

    try{

        String sasToken = "sv=" + azureApiVersion +
            "&ss=f" +
            "&srt=o" +
            "&sp=r" +
            "&se=" +URLEncoder.encode(expiry, "UTF-8") +
            "&st=" + URLEncoder.encode(start, "UTF-8") +
            "&spr=https" +
            "&sig=" + URLEncoder.encode(signature, "UTF-8");

    System.out.println(resourceUrl+"?"+sasToken);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
}

private static String getHMAC256(String accountKey, String signStr) {
    String signature = null;
    try {
        SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(accountKey), "HmacSHA256");
        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        sha256HMAC.init(secretKey);
        signature = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(signStr.getBytes("UTF-8")));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return signature;
}
11.12.2018
  • Дох! Вы абсолютно правы с пунктами 1 и 3 (я пытался с датами закодировать, а не закодировать и просто вставил закодированную версию в моем примере) Спасибо! 11.12.2018
  • В дополнение к вышесказанному - я нашел этот раздел полезным для описания того, что происходит с stringToSign: docs.microsoft.com/en-us/rest/api/storageservices/ 31.05.2019
  • Я столкнулся с проблемой, когда срок действия ссылки для скачивания просто не истек. Оказывается, мой браузер кешировал результат запроса. Попытка использовать ссылку в другом браузере доказала, что срок ее действия действительно истек. См. Это: social.msdn.microsoft.com/Forums/en-US/. Просто выкладываю это ... 19.07.2021

  • 2

    У меня есть способ попроще

    SharedAccessAccountPolicy sharedAccessAccountPolicy = new SharedAccessAccountPolicy();
    sharedAccessAccountPolicy.setPermissionsFromString("racwdlup");
    long date = new Date().getTime();
    long expiryDate = new Date(date + 8640000).getTime();
    sharedAccessAccountPolicy.setSharedAccessStartTime(new Date(date));
    sharedAccessAccountPolicy.setSharedAccessExpiryTime(new Date(expiryDate));
    sharedAccessAccountPolicy.setResourceTypeFromString("sco");
    sharedAccessAccountPolicy.setServiceFromString("bfqt");
    String sasToken = "?" + storageAccount.generateSharedAccessSignature(sharedAccessAccountPolicy);
    

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

    private String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=<storage name>;AccountKey=<your key>;EndpointSuffix=core.windows.net";
    storageAccount = CloudStorageAccount.parse(storageConnectionString);
    
    15.10.2019
  • эй, где я могу получить библиотеку SharedAccessAccountPolicy в mvn? 31.07.2020
  • @Rodolfo Velasco Я думаю, что это был именно этот. mvnrepository.com/artifact/com.microsoft.azure/azure-storage Сообщите мне, если это не сработает, я проверю. 01.08.2020
  • Хорошо, я все равно проверил. Вот она: группа компиляции: 'com.microsoft.azure', имя: 'azure-storage', версия: '8.0.0' Я использовал v8.0.0 на maven, я вижу, что у них есть более новые версии. 01.08.2020
  • Я использовал последнюю версию на тот момент. Мне нужно установить разрешения только для чтения (загрузки), поэтому я изменил racwdlup на r. Кроме того, как вы думаете, необходимо что-либо изменить в setResourceTypeFromString (sco) или setServiceFromString (bfqt) ?. Заранее спасибо. 04.08.2020
  • @Rodolfo Velasco Я, честно говоря, не помню, как эти разрешения работают в Azure, но в их документации было объяснение. 10.08.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..