Как я могу обеспечить обнуление объекта Java (содержащего криптографический материал)? - PullRequest
5 голосов
/ 23 марта 2010

Меня беспокоит то, что криптографические ключи и секреты, которыми управляет сборщик мусора, могут копироваться и перемещаться в памяти без обнуления.

В качестве возможного решения достаточно:

public class Key {
  private char[] key;
  // ...
  protected void finalize() throws Throwable { 
    try {
      for(int k = 0; k < key.length; k++) {
        key[k] = '\0';
      }
    } catch (Exception e) {
      //...
    } finally {
      super.finalize();
    }
  }
  // ...
}

РЕДАКТИРОВАТЬ: Обратите внимание, что моя проблема касается не только обнуления официальной (указанной) копии объекта, но также любых устаревших копий, которые мог сделать сборщик мусора, в то время как он тасует память для экономии места и скорости.

Простейшим примером является GC mark-and-sweep, где объекты помечаются как «ссылающиеся», а затем все эти объекты копируются в другой регион. Остальные же мусор, и поэтому они собираются. Когда происходит копирование, это может привести к тому, что остаточные данные ключа больше не будут управляться сборщиком мусора (поскольку «официальные» данные находятся в новом регионе).

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

Ответы [ 4 ]

4 голосов
/ 23 марта 2010

Справочное руководство по Java Cryptography рекомендует всегда использовать массивы символов вместо строк для паролей, чтобы впоследствии их можно было обнулить.Они также предоставляют пример кода , как вы можете реализовать его .

1 голос
/ 25 марта 2010

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

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

И если вы беспокоитесь о том, что злоумышленник, работающий как обычный пользователь в системе, получает доступ к памяти, отброшенной JVM: AFAIK, все современные ОС перезаписывают вновь выделенную память нулями.

1 голос
/ 23 марта 2010

Лучше всего использовать allocateDirect в NIO. На разумной реализации это не должно быть перемещено. Но он, вероятно, будет иметь право на подкачку на диск (я думаю, вы могли бы опросить) и на спящий режим.

0 голосов
/ 25 марта 2010

Итак, я пришел к выводу от @jambjo и @james, что на самом деле я ничего не могу сделать, чтобы предотвратить копирование ключей и их отсутствие.

Лучшей стратегией для разработчика было бы поместить библиотеку шифрования в C (или любой другой неуправляемый язык) и реализовать там свои вещи.

Я был бы более чем готов принять ответ от кого-то другого, если бы он мог найти лучшее решение.

...