Это вопрос мозгового штурма о том, что возможно в Java (или нет).Я хочу знать, возможно ли скрыть секрет внутри класса и больше не иметь доступа к нему , используя код Java или только его функции (безопасность, рефлексия, сериализация, загрузчики классов, вы-имя-это ...).
Вот что я имею в виду:
public final class Safe {
private String secret;
private HashMap<String, Credentials> validCertificates
= new HashMap<String, Credentials>();
public Safe(String aSecret) {
this.secret = aSecret;
}
public final class Credentials {
private String user;
private Credentials(String user) {
this.user = user;
}
}
public final Credentials getCredential(String user) {
// Following test is just for illustrating the intention...
if ( "accepted".equals(user) ) {
return new Credentials(user);
} else {
return null;
}
}
public String gimmeTheSecret(Credentials cred) {
if ( this.validCertificates.get(cred.user) == cred ) {
return secret;
} else {
return null;
}
}
private void writeObject(ObjectOutputStream stream) throws IOException {
throw new RuntimeException("No no no no no no no!!!");
}
}
Можно ли это улучшить?Должно ли это быть улучшено?Возможно ли реализовать идею блокировки секрета в безопасном классе?
РЕДАКТИРОВАТЬ
Актуальность:
Некоторые людивопрос актуальности вопроса, который я поднимаю здесь.Хотя я задаю общий вопрос для запуска открытого разговора, для этого класса есть очень конкретное приложение:
- Если я хочу расшифровать некоторые сообщения, мне нужно загрузить данные закрытого ключав класс.Если я не могу предотвратить доступ к нему другого Java-кода, невозможно создать безопасную систему.Конечно, если я хочу расшифровать сообщение, мне лучше сделать это в классе, чем выдавать секрет, но, тем не менее, сейф должен оставаться неразрушимым.
Уточнение:
- Экземпляры класса создаются только во время выполнения, а не во время компиляции
- Код может выполняться в приложениях веб-сервера или любых приложениях для настольных компьютеров или устройств
- Класс используется только для хранения секрета во время выполнения, в памяти, нет планов его сохранения (для сохранения можно использовать классические методы шифрования).
Факты:
- Чтобы реализовать защиту в приложении Java, необходимо установить экземпляр SecurityManager, где проверка методы переопределяются по мере необходимости
- Это приложение может загружать недоверенный код с безопаснымзагрузчики классов и назначьте домен защиты для классов, которые он загружает.Этот домен не должен включать в себя RuntimePermission ("setSecurityManager").
- Ненадежный код может пытаться изменить SecurityManager, но поскольку загрузчик защищенных классов не предоставилВ разрешении setSecurityManager будет выдано исключение SecurityException.
Решенные проблемы:
Что касается среды выполнения, нам нужно выделить два случая:
- Контролируемая среда: Мы запускаем приложение, которое будет использовать ненадежный код, пытаясь взломать наш «сейф».
Если мы установим правильный SecurityManager, отключающий отражение и ограничивающий разрешения для любого загруженного ненадежного кода, тогда наш секрет безопасен.
- Неконтролируемая среда: Хакер может запустить приложение, которое использует ненадежный код, пытаясь взломать наш «сейф».
Хакер может создать свое собственное приложение со своим собственным менеджером безопасности и загрузчиком Secure Class.Он может загрузить наш код из пути к классам и выполнить его, как если бы это было наше собственное приложение.В этом случае он может взломать сейф.
- Как установлено в , отдельный вопрос , sun.misc.Unsafe не может взломать менеджер безопасности