Задать вопрос
@Lion97icvc

Как авторизоваться по API в Passbolt?

Добрый день. Нашли неплохую программу Passbolt CE, установили ее на свой сервер, все настроили, теперь хотим логиниться и получать пароли при помощи встроенного API, но возникает ряд проблем.
Сначала расшифровывает приватный ключ:
const fs = require('fs');
const openpgp = require('openpgp');
const axios = require('axios');
require('dotenv').config();

const PRIVATE_KEY = process.env.PRIVATE_KEY;
const PASSPHRASE = process.env.PASSPHRASE;
const EMAIL = process.env.EMAIL;
const API_URL = process.env.API_URL;

async function loadPrivateKey() {
  console.log('[2] Загружаем приватный ключ...');
  const privateKeyArmored = fs.readFileSync(PRIVATE_KEY, 'utf8');
  const privateKey = await openpgp.readPrivateKey({ armoredKey: privateKeyArmored });

  if (privateKey.isDecrypted()) {
    console.log('[INFO]  Ключ уже расшифрован');
    return privateKey;
  }

  const decryptedKey = await openpgp.decryptKey({ privateKey, passphrase: PASSPHRASE });
  console.log('[INFO]  Ключ расшифрован через passphrase');
  return decryptedKey;
}

на этом этапе, если использовать приватный ключ от пользователя, который создавался при настройке приложения все ок, ключ расшифровывается. Если использовать серверный ключ server_private_key.asc, то пишет, что ключ уже расшифрован
следующий этап:
async function getChallenge() {
  console.log('[1] Получаем challenge...');
  const res = await axios.get(`${API_URL}/auth/verify.json?username=${encodeURIComponent(EMAIL)}`);
  const challenge = res.data.body.fingerprint;
  console.log('[CHALLENGE]', challenge);
  return challenge;
}

Вот тут начинается веселье, он получает challenge, который равен fingerprint. Если я использую серверный приватный ключ, то отпечаток полученный от сервера passbolt (A505F33A1191319E787D0B2E5E92BA8A2C424B49, например) будет равен fingerprint этого серверного ключа и код пойдет дальше. Если я буду использовать приватный ключ пользователя, то на этом этапе я получу ошибку, что ❌ Подпись невозможна. Ожидался ключ с fingerprint A505F33A1191319E787D0B2E5E92BA8A2C424B49, но используем 999AAF9999E99999DC999A99CD99B990DE999999.
Если идти по первому пути с серверным приватным ключом, то этот участок проходит без ошибок:
async function signChallenge(challenge, decryptedKey) {
    console.log('[3] Подписываем challenge...');
  
    const message = await openpgp.createMessage({ text: challenge });
    const detachedSignature = await openpgp.sign({
      message,
      signingKeys: decryptedKey,
      detached: true,
      format: 'binary'
    });
  
    const signatureBase64 = Buffer.from(detachedSignature).toString('base64'); // ← здесь исправили
    return signatureBase64;
  }

Ошибка у меня возникает, когда я пытаюсь авторизоваться:
async function loginJWT(fingerprint, signatureBase64) {
  console.log('[4] Выполняем JWT авторизацию...');

  try {
    const response = await axios.post(`${API_URL}/auth/jwt/login.json`, {
      gpg_auth: {
        keyid: fingerprint,
        signature: signatureBase64
      }
    });
    console.log('[✅] Успешный ответ:', response.data);
  } catch (err) {
    if (err.response) {
      console.error('[ОШИБКА ОТ СЕРВЕРА]', err.response.data);
    } else {
      console.error('[ОШИБКА]', err.message);
    }
  }
}

[4] Выполняем JWT авторизацию...
[ОШИБКА ОТ СЕРВЕРА] {
  header: {
    id: 'ff22369f-839f-4041-92ff-ff8af69ff1см',
    status: 'error',
    servertime: 1745821728,
    action: '28c0972f-e6f2-5f44-f5fb-bf2f11799ee1',
    message: 'Учетные данные недействительны.',
    url: '/auth/jwt/login.json',
    code: 400
  },
  body: ''
}

если же я не провожу сравнение на втором этапе с отпечатком от сервера и отпечатком пользователя, то возникает другая ошибка:
[2] Загружаем приватный ключ...
[INFO]  Ключ расшифрован через passphrase
[1] Получаем challenge...
[CHALLENGE] A505F33A1191319E787D0B2E5E92BA8A2C424B49
[3] Подписываем challenge...
[4] Выполняем JWT авторизацию...
[ОШИБКА ОТ СЕРВЕРА] {
  header: {
    id: 'ff22369f-839f-4041-92ff-ff8af69ff1см',
    status: 'error',
    servertime: 1745827074,
    action: '28c0972f-e6f2-5f44-f5fb-bf2f11799ee1',
    message: 'Учетные данные недействительны.',
    url: '/auth/jwt/login.json',
    code: 400
  },
  body: ''
}

подскажите, пожалуйста, что идет не так.
Даже если фиксировать именно свой отпечаток, а не брать полученный от passbolt:
async function loginJWT(signatureBase64) {
  console.log('[4] Выполняем JWT авторизацию...');

  try {
    const response = await axios.post(`${API_URL}/auth/jwt/login.json`, {
      gpg_auth: {
        keyid: FIXED_FINGERPRINT,
        signature: signatureBase64
      }
    });

    console.log('[✅ УСПЕХ] Ответ:', response.data);
  } catch (err) {
    if (err.response) {
      console.error('[ОШИБКА ОТ СЕРВЕРА]', err.response.data);
    } else {
      console.error('[ОШИБКА]', err.message);
    }
  }
}

(async () => {
  const privateKey = await loadPrivateKey();
  const challenge = await getChallenge();
  const signatureBase64 = await signChallenge(challenge, privateKey);
  await loginJWT(signatureBase64);
})();

Я снова получаю ошибку, что message: 'Учетные данные недействительны.',
  • Вопрос задан
  • 9 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы