Pergunta

Eu tenho um código como este em um aplicativo winforms que estava escrevendo para consultar a cota de armazenamento da caixa de correio de um usuário.

DirectoryEntry mbstore = new DirectoryEntry(
      @"LDAP://" + strhome, 
      m_serviceaccount, 
      [m_pwd], 
      AuthenticationTypes.Secure);

Não importa qual abordagem eu tentei (como SecureString), consigo ver facilmente a senha (m_pwd) usando o Reflector ou a guia de strings do Process Explorer para o executável.

Eu sei que poderia colocar esse código no servidor ou aumentar a segurança usando mecanismos como delegação e concedendo apenas os privilégios necessários à conta de serviço.

Alguém pode sugerir uma maneira razoavelmente segura de armazenar a senha no aplicativo local sem revelar a senha aos hackers?

O hash não é possível, pois preciso saber a senha exata (não apenas o hash para fins de correspondência).Os mecanismos de criptografia/descriptografia não funcionam porque dependem da máquina.

Foi útil?

Solução

O método santificado é usar CryptoAPI e APIs de proteção de dados.

Para criptografar, use algo assim (C++):

DATA_BLOB blobIn, blobOut;
blobIn.pbData=(BYTE*)data;
blobIn.cbData=wcslen(data)*sizeof(WCHAR);

CryptProtectData(&blobIn, description, NULL, NULL, NULL, CRYPTPROTECT_LOCAL_MACHINE | CRYPTPROTECT_UI_FORBIDDEN, &blobOut);
_encrypted=blobOut.pbData;
_length=blobOut.cbData;

A descriptografia é o oposto:

DATA_BLOB blobIn, blobOut;
blobIn.pbData=const_cast<BYTE*>(data);
blobIn.cbData=length;

CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut);

std::wstring _decrypted;
_decrypted.assign((LPCWSTR)blobOut.pbData,(LPCWSTR)blobOut.pbData+blobOut.cbData/sizeof(WCHAR));

Se você não especificar CRYPTPROTECT_LOCAL_MACHINE, a senha criptografada poderá ser armazenada com segurança no registro ou no arquivo de configuração e somente você poderá descriptografá-la.Se você especificar LOCAL_MACHINE, qualquer pessoa com acesso à máquina poderá obtê-lo.

Outras dicas

Conforme mencionado, a API de proteção de dados é uma boa maneira de fazer isso.Observe que se você estiver usando o .NET 2.0 ou superior, não será necessário usar P/Invoke para invocar a DPAPI.A estrutura agrupa as chamadas com a classe System.Security.Cryptography.ProtectedData.

Encontrei este livro de Keith Brown O Guia do desenvolvedor .NET para segurança do Windows.Possui alguns bons exemplos cobrindo todos os tipos de cenários de segurança.Livre Versão on-line também está disponível.

Se você armazená-lo como uma string segura e salvá-la em um arquivo (possivelmente usando Armazenamento isolado, a única vez que você terá uma senha em texto simples será quando você a descriptografar para criar seu mbstore.Infelizmente, o construtor não utiliza um objeto SecureString ou Credential.

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