Как мне хранить токены доступа, созданные другим приложением с помощью Google Cloud KMS?

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

Я новичок в Cloud KMS и подобных системах в целом, но последние несколько часов потратил на его изучение. Это кажется идеальным решением для решения моей проблемы, но я не совсем уверен, какой стратегии мне следует придерживаться для хранения этих токенов доступа:

  1. Следует ли хранить ключ шифрования в Cloud KMS и использовать этот ключ шифрования с пакетом NPM, например вот этот хранить токены доступа в моей базе данных?
  2. Следует ли хранить токены доступа напрямую в KMS? Я предполагаю, что у меня будет хранилище ключей и ключи меняются каждые 14 дней. Каждый раз, когда я получаю токен доступа, я просто шифрую его и сохраняю в KMS. Я храню только зашифрованный текст в своей базе данных. Когда мне нужно получить доступ к токену доступа из KMS, я использую зашифрованный текст для его расшифровки.

Что из вышеперечисленного является правильным способом использования KMS? Если это вариант 2, у меня есть дополнительные вопросы:

  • Могу ли я зашифровать большое количество токенов доступа одним ключом или мне нужно создавать новый ключ для каждого токена доступа?
  • Если мне когда-нибудь понадобится изменить токен доступа, зашифрованный в KMS, могу ли я просто изменить его или мне нужно будет уничтожить старую версию и снова зашифровать?

Спасибо за вашу помощь!




Ответы (3)


Я думаю, что ваш лучший вариант - использовать Node.js API, предоставляемый Google, для шифрования токенов и сохранения полученного зашифрованного текста в вашей базе данных.

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

Могу ли я зашифровать большое количество токенов доступа одним ключом или мне нужно создавать новый ключ для каждого токена доступа?

Вы можете зашифровать любое количество токенов одним и тем же ключом. Создание ключа для каждого токена довольно скоро станет неуправляемым, и, если они не будут использовать сам ключ, он будет скомпрометирован (что трудно представить, что он хранится только в Google), нет значительного риска.

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

KMS не хранит ваши данные, ни в зашифрованном виде, ни в виде обычного текста, он просто хранит КЛЮЧ, необходимый для шифрования или расшифровки ваших данных.

Следуя методу хранения только зашифрованной версии токенов, когда вам нужно изменить один токен, это должно выглядеть следующим образом:

  • Клиент отправляет вам токен, который необходимо отозвать.
  • Ваше приложение шифрует его и сравнивает с токенами, хранящимися в БД.
  • Новый токен генерируется (я понимаю, вашим клиентским приложением?)
  • Он отправляется в ваше приложение, которое его шифрует.
  • Старая версия токена заменяется новой версией
  • Теперь клиент может использовать новый токен, так как он имеет такой же срок действия, как и предыдущий. Если он попытается использовать старый токен, поскольку его больше нет в БД, это не сработает.

Что касается ротации ключей, когда это произойдет, новые токены будут зашифрованы новыми ключами. Старые токены по-прежнему нельзя будет зашифровать, потому что ваши старые ключи все еще находятся в KMS и больше не используются для шифрования. Однако если вы уничтожите ключ, которым они были зашифрованы, их невозможно будет восстановить.

person DevopsTux    schedule 14.02.2018

По состоянию на декабрь 2019 г. предпочтительным способом хранения секретов в Google Cloud и управления ими является диспетчер секретов:

$ echo -n "my-access-token" | gcloud beta secrets create "access-token" \
  --data-file=- \
  --replication-policy "automatic"

Затем вы можете получить доступ к секретам из своих приложений. Вот пример с Node:

function getSecret() {
  const [version] = await client.accessSecretVersion({
    name:"projects/<YOUR-PROJECT-ID>/secrets/access-token/versions/1",
  });

  const auth = version.payload.data.toString('utf-8');

  // auth is "my-access-token"
  return auth
}

Любые службы, которым требуется доступ к секрету, нуждаются в roles/secretmanager.secretAccessor разрешениях на секрет.

person sethvargo    schedule 22.12.2019

Ваш вариант 2 подходит, если токены доступа достаточно малы для шифрования с помощью API (несколько тысяч байтов или меньше). Вы можете зашифровать любое количество токенов одним и тем же ключом без ущерба для безопасности.

14-дневная ротация ключей кажется более частой, чем это необходимо, если только в этом нет особой необходимости.

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

person Community    schedule 14.02.2018
comment
Спасибо за ответ. Жетоны доступа <100b, так что я думаю, что это нормально. Что касается моего вопроса о модификации, я имел в виду, что токены доступа, которые я получаю, имеют долгосрочную действительность, но сам токен доступа может измениться (именно так работает приложение). Когда создается новый токен доступа, он имеет такую ​​же силу, что и предыдущий токен доступа, но я больше не могу использовать предыдущий токен доступа. В результате мне нужно обновить исходный токен доступа, который я хранил в KMS. Это выполнимо / рекомендуется? - person JackH; 14.02.2018
comment
Да, если вам нужно сохранить обновленный токен доступа, вы должны зашифровать его и поместить в свое хранилище. - person Tim Dierks; 14.02.2018