Как зашифровать данные с помощью бодрого замка, гарантируя, что результат будет детерминированным - PullRequest
2 голосов
/ 28 марта 2019

Задача

Мы хотим зашифровать личную информацию. Они не должны быть читаемыми. Однако, поскольку результаты также будут использоваться для машинного обучения, каждый раз, когда значение (скажем, «ABC») шифруется, результирующие данные должны быть одинаковыми.

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

Context

Мы решили использовать надувной замок , потому что он поддерживает большое количество режимов шифрования, включая (очевидно, быстрый ECC). Поскольку мы говорим о шифровании нескольких ТБ в день, было бы неплохо иметь хорошую производительность.

Решение проблем

Несмотря на то, что библиотека надувных замков хорошо написана, кажется, трудно найти хорошую документацию и примеры использования. Я изо всех сил пытаюсь найти свою точку входа. Нужно ли смотреть на пакет org.bouncycastle.crypto или org.bouncycastle.crypto.engines? или crypto.ec? Я нашел класс ZeroBytePadding, который, как мне кажется, должен указать мне на потенциальный двигатель, который делает то, что я хочу, но я не могу найти то, что я ищу.

Цель

Класс, имеющий набор методов, подобных этому:

class Anonomyzer{
  def initialize(publicKey: String, privateKey: String): Unit
  def encode(data: Array[Byte]): Array[Byte]
  def decode(data: Array[Byte]): Array[Byte]
}

Следующий код должен быть верным

Anonomyzer.initialize("PUBLIC", "PRIVATE")
val once = Anonomyzer.encode(data)
val twice = Anonomyzer.encode(data)
Arrays.equals(once, twice)

Edit: Я прочитал больше об этом и обнаружил, что то, что я ищу, называется Электронная кодовая книга Режим работы. Хотя это не совсем безопасно, это лучшее, что мы можем надеяться на AFAIK.

1 Ответ

1 голос
/ 01 апреля 2019

Однако, поскольку результаты также будут использоваться для машинного обучения, каждый раз, когда значение (скажем, «ABC») шифруется, результирующие данные должны быть одинаковыми

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

Просто предложения:

  • Вы можете анонимизировать набор данных обучения, отбирать данные их PII и агрегировать их до разумного уровня, все еще ценного для ML.Я бы предпочел эту опцию, потому что тогда она чистая, не рискуя нарушить какие-либо правила или утечку защищенной информации
  • Вы можете хешировать PII (или категориальные данные), что обеспечило бы уникальное отображение без обратимого отображения (хотя всегда будетсопоставление с исходными значениями)
  • для количественных данных вы можете искать «шифрование с сохранением порядка», которое может быть нетривиальным для правильной работы (это одна из причин, почему я выбрал бы 1-й вариант)

Использование ярлыков (с использованием ECB или статического IV) в некоторых случаях может полностью нарушить безопасность зашифрованных данных.Поэтому до тех пор, пока вы действительно не поймете, что делаете, вы можете застрелиться себе в ногу

Мы решили использовать надувной замок, поскольку он поддерживает большое количество режимов шифрования, в том числе (по-видимому, быстрый ECC)

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

очевидно быстрый ECC).Поскольку речь идет о шифровании нескольких ТБ в день, было бы неплохо иметь хорошую производительность

ECC по-прежнему остается асимметричным шифрованием, обычно используемым для гибридного шифрования (шифрование симметричного ключа шифрования данных).Поэтому, если вы стремитесь к скорости, вы можете проверить, поддерживает ли ваша JVM и ВМ встроенную поддержку AES-NI, или использовать какой-нибудь быстрый шифр (сальса, ...)Шифрование обычно не является узким местом производительности, если все сделано правильно

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

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

Security.addProvider(new BouncyCastleProvider());
... 
 Cipher cipher = Cipher.getInstance("AES/OFB/NoPadding", "BC");

или

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");

Редактировать: фиксированные комбинации дополнения

...