Pergunta

Dentro de um aplicativo, tenho chaves secretas usadas para calcular um hash para uma chamada de API.Em uma aplicação .NET é bastante fácil usar um programa como o Reflector para extrair informações do assembly para incluir essas chaves.

Ofuscar a montagem é uma boa maneira de proteger essas chaves?

Foi útil?

Solução

Provavelmente não.

Examine a criptografia e os mecanismos internos de ocultação de informações do Windows (DPAPI e armazenamento de chaves em uma chave de registro restrita a ACL, por exemplo).Isso é o melhor que você obterá em termos de segurança necessária para manter o mesmo sistema que seu aplicativo.

Se você está procurando uma maneira de impedir que alguém fisicamente sentado em frente à máquina obtenha suas informações, esqueça.Se alguém for determinado e tiver acesso irrestrito a um computador que não está sob seu controle, não há como ter 100% de certeza de que os dados estão protegidos em todas as circunstâncias.Alguém que está determinado conseguirá se quiser.

Outras dicas

Eu não pensaria assim, já que ofuscar (pelo menos pelo que entendi) simplesmente mexerá com os nomes dos métodos para dificultar (mas não impossível) a compreensão do código.Isso não alterará os dados da chave real (que acho que você armazenou em uma constante em algum lugar).

Se você quiser apenas tornar isso um pouco mais difícil de ver, você pode executar uma cifra simples no texto simples (como ROT-13 ou algo assim) para que pelo menos não seja armazenado de forma clara no próprio código.Mas isso certamente não impedirá que qualquer hacker determinado acesse sua chave.Um método de criptografia mais forte não ajudará porque você ainda precisará armazenar a chave ISSO no código e não há nada que proteja isso.

A única coisa realmente segura que consigo pensar é manter a chave fora do aplicativo de alguma forma e, em seguida, restringir o acesso à chave.Por exemplo, você poderia manter a chave em um arquivo separado e depois proteger o arquivo com uma restrição baseada no usuário no nível do sistema operacional;isso provavelmente funcionaria.Você poderia fazer o mesmo com uma conexão de banco de dados (novamente, contando com a restrição de acesso baseada no usuário para manter usuários não autorizados fora do banco de dados).

Brinquei com a ideia de fazer isso em meus aplicativos, mas nunca a implementei.

DannySmurf está certo ao dizer que você não pode ocultar as chaves da pessoa que executa um aplicativo;se o aplicativo pode acessar as chaves, a pessoa também pode.

No entanto, o que você está tentando realizar exatamente?

Dependendo do que for, muitas vezes existem maneiras de atingir seu objetivo que não dependem simplesmente de manter um “segredo” secreto na máquina do seu usuário.

Atrasado para o jogo aqui...

A abordagem de armazenar as chaves na configuração do assembly/assembly é fundamentalmente insegura.Não há nenhuma maneira rígida de armazená-lo, pois um determinado usuário terá acesso.Não me importo se você usa o melhor/mais caro produto de ofuscação do planeta.Não me importo se você usa PDAPI para proteger os dados (embora seja melhor).Não me importo se você usa um armazenamento de chaves local protegido pelo sistema operacional (isso é ainda melhor).Nenhum é ideal, pois todos sofrem do mesmo problema central:o usuário tem acesso às chaves, e elas permanecem lá, imutáveis ​​por dias, semanas, possivelmente até meses e anos.

Uma abordagem muito mais segura seria proteger suas chamadas de API com PKI testada e comprovada.No entanto, isso tem uma sobrecarga óbvia de desempenho se suas chamadas de API forem tagarelas, mas para a grande maioria dos aplicativos isso não é problema.

Se o desempenho for uma preocupação, você pode usar Diffie-Hellman em vez de PKI assimétrica para estabelecer uma chave simétrica secreta compartilhada para uso com uma cifra como AES."compartilhado" neste caso significa compartilhado entre cliente e servidor, não todos os clientes/usuários.Não há nenhuma chave codificada/incorporada.Em qualquer lugar.

As chaves são transitórias, regeneradas toda vez que o usuário executa o programa ou, se você for realmente paranóico, elas podem expirar e exigir recreação.

As próprias chaves simétricas secretas compartilhadas computadas são armazenadas apenas na memória, em SecureString.Eles são difíceis de extrair e, mesmo que você o faça, eles são válidos apenas por um período muito curto e apenas para comunicação entre aquele cliente específico (ou seja, aquela sessão).Em outras palavras, mesmo que alguém hackeie suas chaves locais, elas só servem para interferir na comunicação local.Eles não podem usar esse conhecimento para afetar outros usuários, ao contrário de uma chave integrada compartilhada por todos os usuários por meio de código/configuração.

Além disso, as chaves inteiras nunca são passadas pela rede.O cliente Alice e o servidor Bob os calculam de forma independente.As informações que eles passam para fazer isso poderiam, em teoria, ser interceptadas por um terceiro Charlie, permitindo-lhe calcular de forma independente a chave secreta compartilhada.É por isso que você usa essa PKI assimétrica (significativamente mais cara) para proteger a geração de chaves entre Alice e Bob.

Nestes sistemas, a geração de chaves é muitas vezes associada à autenticação e, portanto, à criação de sessões.Você "faz login" e cria sua "sessão" via PKI e, após a conclusão, tanto o cliente quanto o servidor possuem independentemente uma chave simétrica que pode ser usada para criptografia mais rápida em ordem de magnitude para todas as comunicações subsequentes nessa sessão.Para servidores de alta escala, isso é importante para economizar ciclos de computação na descriptografia em vez de usar, digamos, TLS para tudo.

Mas espere:ainda não estamos seguros.Apenas impedimos a leitura das mensagens.

Observe que ainda é necessário usar um mecanismo de resumo de mensagens para evitar a manipulação do intermediário.Embora ninguém possa ler os dados transmitidos, sem um MD nada os impede de modificá-los.Então você faz o hash da mensagem antes da criptografia e depois envia o hash junto com a mensagem.O servidor então faz um novo hash da carga após a descriptografia e verifica se ela corresponde ao hash que fazia parte da mensagem.Se a mensagem foi modificada em trânsito, eles não o farão e toda a mensagem será descartada/ignorada.

O mecanismo final necessário para se proteger são os ataques de repetição.Neste ponto, você impediu que as pessoas lessem seus dados, bem como modificassem seus dados, mas não os impediu de simplesmente enviá-los novamente.Se isso for um problema para seu aplicativo, seu protocolo deverá fornecer dados e tanto o cliente quanto o servidor deverão ter informações de estado suficientes para detectar uma repetição.Isso pode ser algo tão simples quanto um contador que faz parte da carga criptografada.Observe que se você estiver usando um transporte como o UDP, provavelmente já possui um mecanismo para lidar com pacotes duplicados e, portanto, já pode lidar com ataques de repetição.

O que deveria ser óbvio é que acertar não é fácil.Portanto, use PKI, a menos que ABSOLUTAMENTE não possa.

Observe que essa abordagem é muito usada na indústria de jogos, onde é altamente desejável gastar o mínimo possível de computação em cada jogador para obter maior escalabilidade e, ao mesmo tempo, fornecer segurança contra hackers/olhos indiscretos.

Concluindo, se isso é realmente algo que preocupa, em vez de tentar encontrar um armazenamento seguro das chaves de API, não faça isso.Em vez disso, altere a forma como seu aplicativo usa essa API (supondo que você tenha controle de ambos os lados, naturalmente).Use uma PKI ou um híbrido simétrico compartilhado pela PKI se a PKI for muito lenta (o que RARAMENTE é um problema atualmente).Então você não terá nada armazenado que seja uma preocupação de segurança.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top