2016-11-30 8 views
0

Мне нужно сильно зашифровать некоторые данные в моем приложении ASP.NET Core.Безопасный закрытый ключ (RSA) с паролем пользователя (AES)

Идея была: У пользователя будет хешированный пароль. Пользователь также будет иметь асимметричный ключ (RSA-512). Открытый ключ хранится в БД. Закрытый ключ сначала шифруется симметричным ключом (AES-256). В качестве ключа для этого шифрования мы используем простой/текстовый пароль пользователя.

Если я хочу создать что-то в качестве примера автомобиля. Я создам открытый и закрытый ключ для этого конкретного автомобиля. Открытые ключи сохраняются в виде обычного текста. Закрытый ключ шифруется с помощью открытого ключа создателя «автомобиля» (пользователя).

Поля, принадлежащие автомобилю, зашифрованы открытым ключом автомобиля.

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

Но для того, чтобы стать закрытым ключом пользователя, мне нужно расшифровать его с помощью обычного/текстового пароля. Этот пароль доступен только один раз @ логин (он нигде не хранится).

Проблема, с которой я сталкиваюсь сейчас, заключается в том, что я использую систему логирования с идентификатором IdentityServer 4. Это другой «проект», чем мой API-проект.

Но мне нужен пароль в API, потому что он выполняет мою «бизнес-логику».

РЕАЛЬНАЯ ПРОБЛЕМА НАЧАЛА ЗДЕСЬ:

Чтобы решить эту проблему:

Я думал о добавлении «маршрут» в моей API, что мой проект Логин может позвонить. Таким образом, каждый раз, когда пользователь регистрируется в проекте входа, будет выполняться вызов REST с правильным API с сообщением: «Вот расшифрованная версия закрытого ключа пользователя X».

В настоящий момент API будет хранить его в базе данных EF Core InMemory. Каждый раз, когда пользователь должен расшифровывать данные своего автомобиля. Мне нужно получить закрытый ключ из базы данных «InMemory».

Проблема У меня здесь. Используется ли для этой цели база данных EF 'InMemory'? Похоже, он используется только в качестве демонстрации или в качестве цели тестирования.

Когда я удаляю секретные ключи для памяти. Если пользователь logsout я могу управлять им. Но когда пользователь «истекает», я не могу запускать это. Таким образом, его расшифрованный секретный ключ будет продолжать жить в памяти.

Насколько надежна база данных «InMemory»? Когда он «очищает» себя?

Я с удовольствием получаю полезные советы.

С уважением, Брехт

+1

InMemoryDB предназначен для модульного тестирования в основном, где вы можете использовать его для заполнения и возврата данных вместо того, чтобы полагаться на реальную базу данных. – Tseng

+0

Также: я не эксперт по безопасности, но ваша система/логика кажется довольно ошибочной и превосходит основы безопасности , Закрытый ключ никогда не должен покидать пользователей, но то, что вы на самом деле хотите сделать, это зашифровать его с помощью симметрического шифрования и затем расшифровать его на сервере? Это означает, что и «клиент», и «сервер» должны это знать. Это бьет всю цель этого, и вы могли бы просто отправить секретный ключ, незашифрованный с помощью SSL, и иметь тот же уровень безопасности, также хешированный пароль, который должен быть таким же секретным, теперь просто заменен/использован как пароль в «открытом тексте» ». – Tseng

+0

Злоумышленнику больше не нужен реальный пароль, ему просто нужно будет получить хэши из вашей базы данных Identity servers для доступа и дешифрования всех данных. Где здесь охрана? Вы ничего не выиграли **. Это может работать только тогда, когда пароль пользователя используется напрямую, и только тогда, когда он вводит его для дешифрования некоторых данных на клиенте и отправки их обратно на сервер по защищенному каналу (SSL с проверкой и т. Д.) – Tseng

ответ

1

Вопросы безопасности в стороне (см комментариев), то InMemoryDatabase в основном там для тестирования или дб меньше учебников. Все, что вы добавляете к нему, остается там до deleted (а иногда и мусора, который вы на самом деле не контролируете!) Или DbContext.

Вместо базы данных InMemory EF Core имеет смысл использовать кеш памяти (распределенный или локальный).

Вы можете, конечно, использовать распределенный кеш, такой как Redis, и безопасно расшифровать закрытый ключ в нем и вызвать его из вашей службы. Вы можете добавить дату expiry, когда ключ становится недействительным, и его необходимо запросить или продлить срок действия, вызвав expire command на ключ, и когда пользователь выйдет из системы, удалите ключ с del.

Он также хорошо работает, если вы масштабируете свои серверы. Если вы начинаете с Microsoft.Extensions.Caching.Memory, вы можете легко переключиться на Redis позже, так как оба они реализуют интерфейс IDistributableCache, просто измените конфигурацию в классе запуска.

Возможно, вы захотите попробовать с помощью SecureString (см. here), который непосредственно не реализован в .NET Core, но доступен как дополнительный пакет here), чтобы он был как можно короче в локальной памяти, и не полагаться на то, что GC делает это в какой-то момент.