Как мне сгенерировать правильный TOTP с Node с правильными заголовками и хешированным токеном SHA512? - PullRequest
1 голос
/ 07 апреля 2020

В недавнем школьном проекте, который мне назначили, есть проблема с кодированием, которую мы должны выполнить. Конкурс состоит из нескольких частей, а последняя часть - загрузка в частное репозиторий GitHub и отправка запроса на завершение путем выполнения запроса POST при определенных условиях.

Я успешно выполнил другие части конкурса и застрял при подаче запроса. Представление должно соответствовать следующим правилам:

Построить запрос решения

Сначала создайте строку JSON, как показано ниже:

{

"github_url": "https://github.com/YOUR_ACCOUNT/GITHUB_REPOSITORY",

"contact_email": "YOUR_EMAIL"

}

Введите свой адрес электронной почты для YOUR_EMAIL и личный Github хранилище с вашим решением в YOUR_ACCOUNT/GITHUB_REPOSITORY. Затем выполните HTTP-запрос POST по следующему URL-адресу со строкой JSON в качестве части тела.

CHALLENGE_URL

Тип содержимого

Content-Type: запроса должен быть application/json.

Авторизация

URL-адрес защищен HTTP Basi c Аутентификация, которая поясняется в Глава 2 RFC2617, поэтому вы должны указать поле заголовка Authorization: в своем запросе POST.

  • Для ИД пользователя аутентификации HTTP Basi c используйте тот же адрес электронной почты, который вы указали в JSON строка.
  • В качестве пароля укажите 10-значный git основанный на времени одноразовый пароль, соответствующий TOTP RFC6238.

Пароль авторизации

Для генерации пароля TOTP вам потребуется использовать следующую настройку:

  • Вам необходимо сгенерировать правильный пароль TOTP в соответствии с RFC6238
  • TOTP Time Step X составляет 30 секунд. T0 равно 0.
  • Используйте HMAC-SHA-512 для функции ha sh вместо значения по умолчанию HMAC-SHA-1.
  • Общий секретный ключ токена - это идентификатор пользователя, за которым следует строковое значение ASCII "APICHALLENGE" (не включая двойные кавычки).

Примеры общего секрета

Например, если идентификатор пользователя "email@example.com", общий секрет токена "email@example.comAPICHALLENGE" (без кавычек).

Если ваш запрос POST завершается успешно, сервер возвращает код состояния HTTP 200.

Я пытался следовать этой схеме очень внимательно и по-разному проверяю мою работу. Однако, кажется, я не могу понять это правильно. Мы должны сделать запрос от серверной части Node. Это то, что я сделал до сих пор. Я создал новый npm проект с npm init и установил зависимости, которые вы увидите в коде ниже:

const axios = require('axios');
const base64 = require('base-64');
const utf8 = require('utf8');

const { totp } = require('otplib');


const reqJSON = 
{
    github_url: GITHUB_URL,
    contact_email: MY_EMAIL
}
const stringData = JSON.stringify(reqJSON);

const URL = CHALLENGE_URL;
const sharedSecret = reqJSON.contact_email + "APICHALLENGE";

totp.options = { digits: 10, algorithm: "sha512" }

const myTotp = totp.generate(sharedSecret);
const isValid = totp.check(myTotp, sharedSecret);

console.log("Token Info:", {myTotp, isValid});




const authStringUTF = reqJSON.contact_email + ":" + myTotp;
const bytes = utf8.encode(authStringUTF);
const encoded = base64.encode(bytes);



const createReq = async () =>
{

    try 
    {

        // set the headers
        const config = {
            headers: {
                'Content-Type': 'application/json',
                "Authorization": "Basic " + encoded
            }
        };

        console.log("Making req", {URL, reqJSON, config});

        const res = await axios.post(URL, stringData, config);
        console.log(res.data);
    }
    catch (err)
    {
        console.error(err.response.data);
    }
};

createReq();

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

Я обнаружил, что пакет npm otplib может удовлетворить эти требования с параметрами, которые я передал.

Однако мое решение неверно. Когда я пытаюсь отправить свое решение, я получаю сообщение об ошибке "Invalid token, wrong code". Может кто-нибудь, пожалуйста, помогите мне понять, что я делаю неправильно?

Я действительно не хочу, чтобы весь мой тяжелый труд был напрасным, так как это был длительный проект.

Спасибо вам большое заранее за ваше время и помощь в этом. Я очень благодарен.

1 Ответ

2 голосов
/ 09 апреля 2020

Файл Readme пакета otplib гласит:

// TOTP defaults
{
  // ...includes all HOTP defaults
  createHmacKey: totpCreateHmacKey,
  epoch: Date.now(),
  step: 30,
  window: 0,
}

Таким образом, значение по умолчанию для epoch (T0) равно Date.now(), что является стандартом RF C. Описание задачи определяет, что T0 равно 0.

Необходимо изменить значение по умолчанию для epoch на 0:

totp.options = { digits: 10, algorithm: "sha512", epoch: 0 }
...