Pode um segredo ser oculto em uma classe java 'segura' que oferece credenciais de acess
Esta é uma pergunta de brainstorming sobre o que é possível em Java (ou não). Quero saber se é possível ocultar um segredo dentro de uma classe e impedir mais de acessá-lo usando código Java ou apenas qualquer um de seus recursos (segurança, reflexão, serialização, carregadores de classes, você escolhe ...
Aqui está o que tenho em mente até agora:
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!!!");
}
}
Pode ser melhorado? Deveria ser melhorado? É impossível alcançar a ideia de guardar um segredo em uma classe segura?
EDITA
Relevância
Algumas pessoas questionam a relevância da questão que estou levantando aqui. Embora eu esteja fazendo uma pergunta geral para iniciar uma conversa aberta, há uma aplicação muito concreta para esta classe:
Se eu quiser descriptografar algumas mensagens, preciso carregar os dados da chave privada em uma classe. Se não posso impedir que outro código Java acesse, é impossível criar um sistema seguro. Obviamente, se eu quiser descriptografar uma mensagem, prefiro fazê-lo na classe do que revelar o segredo, mas ainda assim o cofre deve permanecer inquebrável.Esclarecimento
s instâncias da classe são criadas apenas no tempo de execução, não no tempo de compilaçã @Code pode ser executado em aplicativos de servidor Web ou em qualquer aplicativo de desktop ou dispositivo A classe é usada apenas para armazenar um segredo em tempo de execução, na memória, sem planos de persistir (para persistência, pode-se / deve-se usar técnicas clássicas de criptografia)Facts:
Para implementar a segurança em um aplicativo Java, deve-se definir uma instância do SecurityManager em que verificando métodos são substituídos conforme necessárioEste aplicativo pode carregar código não confiável com carregadores de classe seguros e atribuir um domínio de proteção para as classes que ele carrega. Este domínionão deveri inclua uma RuntimePermission ("setSecurityManager"). O código não confiável pode tentar alterar o SecurityManager, mas como o Secure Class Loader não concedeu a permissão setSecurityManager, uma SecurityException será lançadProblemas resolvidos:
Quanto ao ambiente de execução, precisamos distinguir dois casos:
Ambiente controlado: Começamos o aplicativo que usará código não confiável, tentando quebrar nosso 'seguro'.Se definirmos um SecurityManager adequado para desativar a reflexão e restringir as permissões em qualquer código não confiável carregado, nosso segredo estará seguro.
Ambiente não controlado: O hacker começa a iniciar o aplicativo que usa código não confiável tentando quebrar nosso 'seguro'.O hacker pode criar seu próprio aplicativo com seu próprio gerenciador de segurança e carregador Secure Class. Ele poderia carregar nosso código do caminho de classe e executá-lo como se fosse nosso próprio aplicativo. Nesse caso, ele poderia arrombar o cofr
Como estabelecido em uma pergunta separada, sun.misc.Unsafe não pode interromper um gerenciador de segurança