Лучшие практики для (симметричного) шифрования в .Net?

Что считается «наилучшей практикой» для шифрования определенных конфиденциальных или личных данных в базе данных SQL (в соответствии с PCI, HIPAA или другими применимыми стандартами соответствия)?

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

  • Используйте CryptoAPI и Rijndael
  • Создайте IV и сохраните его с зашифрованными данными
  • Используйте DPAPI (область действия компьютера) для «защиты» симметричного ключа.
  • Храните симметричный ключ в реестре, файле или базе данных, разделяйте ключ и храните части в нескольких местах для дополнительной защиты.
  • не расшифровывайте данные, если они действительно не нужны, то есть не после чтения из базы данных. Вместо этого держите зашифрованный текст в памяти.

Это адекватно? Устарело? Безопасно для аудита? Безрассудный?


person cdonner    schedule 13.03.2014    source источник
comment
С точки зрения безопасности, я не думаю, что имеет значение, используете ли вы CryptoAPI — до тех пор, пока вы используете Rijndael или AES (в настоящее время). Например, для этого можно использовать надувной замок. Хранение IV независимо от зашифрованных данных кажется более безопасным. Хранение симметричного ключа на другом оборудовании — более безопасном — всегда предпочтительнее. И храните неконфиденциальные данные только тогда, когда это возможно. например если вам не нужен номер социального обеспечения, не используйте его в качестве идентификатора. Сказав это, ответы на этот вопрос, вероятно, будут основаны на мнении.   -  person Peter Ritchie    schedule 13.03.2014
comment
@PeterRitchie Сохранение IV в секрете не принесет вам многого. Например, с AES-CBC все, что он предотвращает, — это расшифровка первых 16 байтов. Все остальное можно восстановить без капельницы.   -  person CodesInChaos    schedule 13.03.2014
comment
@CodesInChaos Согласен, я только сказал более безопасный.   -  person Peter Ritchie    schedule 13.03.2014
comment
@Wolfwyrd, за исключением того, что это вопрос, специфичный для php, и у него есть некоторые ответы, специфичные для php.   -  person Peter Ritchie    schedule 13.03.2014
comment
Это зависит от соблюдения. В HIPAA, если это закрытая система, я не уверен, что вы должны шифровать. Конечно, вероятно, не лучшая практика. Но соответствие и физическая безопасность являются факторами. Вы смотрите на правильные вещи.   -  person paparazzo    schedule 13.03.2014


Ответы (4)


Ваш подход хорош, с некоторыми корректировками на мой взгляд (обычно я кодирую для соответствия PCI):

Используйте CryptoAPI и Rijndael

Используйте как минимум Rijndael/AES256 независимо от других API.

Создайте IV и сохраните его с зашифрованными данными

Хорошо

Используйте DPAPI (область действия компьютера) для «защиты» симметричного ключа.

Не уверен, что это имеет значение. Я бы просто оставил IV рядом с зашифрованными данными или, если вы действительно параноик, на каком-то другом носителе. Убедитесь, что IV не доступен для общественности.

Храните симметричный ключ в реестре, файле или базе данных, разделяйте ключ и храните части в нескольких местах для дополнительной защиты.

Хранение в нескольких местах не поможет вам, если кто-то украдет ваш носитель. Это немного излишество, чтобы разбить ключ на части, но определенно НЕ храните его вместе с IV и/или зашифрованным текстом. Это было бы плохо.

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

Определенно. Хранить зашифрованный текст в памяти в порядке, но никуда его не передавать, и не расшифровывать, кроме как в случае крайней необходимости, и даже тогда не ВЫСТАВЛЯТЬ весь незашифрованный набор данных - только то, что от него нужно по минимуму. Кроме того, по возможности не держите ключ в памяти — его может обнаружить дамп памяти.

Дополнения:

  • В какой бы базе данных вы ни хранили свой зашифрованный текст, полностью ограничьте доступ для чтения теми процессами, которые выбираются для данного идентификатора. Не разрешайте доступ для чтения к таблицам, в которых хранятся эти данные, НИКОМУ, даже учетной записи SA. Таким образом, человеку, который взломает вашу систему, будет трудно получить ваши зашифрованные тексты, не зная, какие идентификаторы искать. Сделайте то же самое для любой таблицы (таблиц), ссылающихся на идентификатор в таблице зашифрованного текста. НЕ ДОПУСКАЕТСЯ ЧИТАТЬ ЭТИ ТАБЛИЦЫ!
  • Ограничить доступ к базе данных по IP
  • Никогда не сохраняйте незашифрованный открытый текст в памяти поверх состояния. Разрешить его разыменование/сборку мусора, как только запрос будет выполнен.
  • Ограничьте серверы, на которых выполняется этот код, как можно меньшим числом пользователей.
  • Возможно комбинирование методов шифрования для более надежного зашифрованного текста (например, AES + Blowfish)

Надеюсь, это поможет. Некоторые из них являются моим личным мнением, но, насколько мне известно, остаются совместимыми с PCI.

person Haney    schedule 13.03.2014
comment
Вы сказали Убедитесь, что IV не доступен для публики. Но разве хранение IV вместе с зашифрованными данными не делает их общедоступными? Кроме того, я подумал, что было бы нормально сделать IV общедоступным, если один и тот же IV не используется глобально — в идеале он должен быть уникальным для каждого зашифрованного текста (то есть зашифрованного значения). - person Mass Dot Net; 15.09.2020

Я видел, что в одном из предыдущих комментариев упоминалось, что не имеет значения, используете ли вы CryptoAPI. Я просто хотел указать, что CryptoAPI совместим с FIPS 140-2, в то время как Bouncy Castle и встроенные управляемые классы (все те, которые имеют «Управляемый» в конце их имен в пространстве имен System.Security.Cryptography) не соответствуют. . Если у вас есть требование соответствия FIPS, вероятно, проще всего использовать CryptoAPI.

person pretzeldawg    schedule 30.06.2015
comment
Стоит отметить, что FIPS требует слабой безопасности. Избегайте этого, если только АНБ не требует этого. - person o11c; 30.06.2015
comment
...или любой другой клиент/заинтересованное лицо требует этого. Если это требование, то это требование. Если это не требование, тогда весь мир в ваших руках... или, по крайней мере, немного. ;) - person pretzeldawg; 02.07.2015
comment
вы всегда можете зашифровать с помощью надежного шифра (Rijndael), а затем зашифровать его с помощью обязательного решения. как правило, мандаты - это пол, а не потолок. - person matao; 27.04.2020

я бы добавил:

  • Скрывать IV не важно. Это нормально, если IV является общедоступным. Просто используйте хорошие IV, а это значит, используйте криптографически стойкий генератор случайных чисел, чтобы ваши IV были неотличимы от случайных.

  • Хранение ключа шифрования отдельно от данных, которые он шифрует.

  • Добавьте аутентификацию к вашему шифрованию. Например, добавьте ключ HMAC со вторым симметричным ключом шифрования, покрывающим зашифрованный текст. Если вы не используете какую-либо форму аутентифицированного шифрования, то ваш зашифрованный текст может быть изменен, и вы не сможете узнать об этом (AES отлично расшифрует мусор). Вы хотите, чтобы любое вмешательство в зашифрованный текст было замечено.

person Jim Flood    schedule 01.07.2015
comment
Я знаю, что прошло 5 лет с тех пор, как вы опубликовали это, но не могли бы вы пояснить последний пункт, касающийся HMAC? Как это будет работать при шифровании одного или нескольких значений по сравнению со стандартным симметричным шифрованием? - person Mass Dot Net; 15.09.2020
comment
@MassDotNet Шифрование с проверкой подлинности Google en.wikipedia.org/wiki/Authenticated_encryption. Кроме того, режим AES GCM в качестве примера. Если вы используете режим GCM, вы получаете аутентифицированное шифрование. - person Jim Flood; 19.09.2020
comment
Отлично, спс за ответ и ссылку! - person Mass Dot Net; 23.09.2020

Взято более общий список рекомендаций из OWASP (памятка по криптографическому хранилищу):

  • Use strong approved cryptographic algorithms
    • Do not implement an existing cryptographic algorithm on your own
    • Используйте для хеширования только утвержденные общедоступные алгоритмы, такие как AES, криптография с открытым ключом RSA и SHA-256 или лучше.
    • Не используйте слабые алгоритмы, такие как MD5 или SHA1.
    • Избегайте хэширования для хранения паролей, вместо этого используйте Argon2, PBKDF2, bcrypt или scrypt.
  • Use approved cryptographic modes
    • In general, you should not use AES, DES or other symmetric cipher primitives directly. NIST approved modes should be used instead. Quote from Nist: "The approved algorithms for encryption/decryption are symmetric key algorithms: AES and TDEA."
  • Используйте сильные случайные числа
  • Убедитесь, что любой секретный ключ защищен от несанкционированного доступа

Кроме того, в соответствии с этим Cisco статья:

  • Следует избегать DES, а также RSA-768, -1024.
  • Допустимы RSA-2048 и RSA-3072.
  • Режим AES-CBC приемлем, в то время как
  • Режим AES-GCM является частью шифрования следующего поколения.
person Ioanna    schedule 29.08.2018
comment
Я не понимаю, что прямо означает [использование] примитивов симметричного шифрования. В цитате NIST говорится, что AES является утвержденным алгоритмом симметричного ключа — разве это не означает, что я могу использовать AES? - person Mass Dot Net; 24.09.2020