Fique à vontade para me corrigir se minhas suposições estiverem erradas aqui, mas deixe-me explicar por que estou perguntando.
Retirado do MSDN, a SecureString
:
Representa o texto que deve ser mantido em sigilo. O texto é criptografado para privacidade ao ser usado e excluído da memória do computador quando não é mais necessário.
Eu entendo isso, faz todo o sentido armazenar uma senha ou outras informações particulares em um SecureString
over a System.String
, porque você pode controlar como e quando ele é realmente armazenado na memória, porque System.String
:
é imutável e, quando não é mais necessário, não pode ser programado de forma programática para a coleta de lixo; isto é, a instância é somente leitura depois de criada e não é possível prever quando a instância será excluída da memória do computador. Conseqüentemente, se um objeto String contiver informações confidenciais, como senha, número do cartão de crédito ou dados pessoais, existe o risco de as informações serem reveladas depois de usadas, porque o aplicativo não pode excluir os dados da memória do computador.
No entanto, no caso de um aplicativo GUI (por exemplo, um cliente ssh), SecureString
ele deve ser construído a partir de a System.String
. Todos os controles de texto usam uma sequência como seu tipo de dados subjacente .
Portanto, isso significa que toda vez que o usuário pressiona uma tecla, a string antiga que estava lá é descartada e uma nova string é criada para representar qual é o valor dentro da caixa de texto, mesmo se estiver usando uma máscara de senha. E não podemos controlar quando ou se algum desses valores é descartado da memória .
Agora é hora de fazer login no servidor. Adivinha? Você precisa passar uma string pela conexão para autenticação . Então, vamos converter nosso SecureString
em um System.String
.... e agora temos uma string no heap sem nenhuma maneira de forçá-lo a passar pela coleta de lixo (ou escrever 0 no seu buffer).
Meu ponto é : não importa o que você faz, em algum lugar ao longo da linha, que SecureString
está indo para ser convertido em um System.String
, o que significa que vai pelo menos existem na pilha em algum ponto (sem qualquer garantia de coleta de lixo).
O que eu quero dizer não é : se existem maneiras de contornar o envio de uma string para uma conexão ssh ou contornar o fato de um controle armazenar uma string (faça um controle personalizado). Para esta pergunta, você pode substituir "conexão ssh" por "formulário de login", "formulário de registro", "formulário de pagamento", "alimentos que você alimentaria seu filhote de cachorro, mas não seus filhos", etc.
- Então, em que momento o uso de um
SecureString
realmente se torna prático? - Vale a pena o tempo extra de desenvolvimento para erradicar completamente o uso de um
System.String
objeto? - O
SecureString
objetivo é simplesmente reduzir a quantidade de tempoSystem.String
em que está na pilha (reduzindo o risco de mudar para um arquivo de troca físico)? - Se um invasor já tem os meios para uma inspeção de pilha, então provavelmente (A) já tem meios para ler as teclas digitadas, ou (B) já possui fisicamente a máquina ... Então, usando um
SecureString
impedimento ele chegaria ao dados de qualquer maneira? - Isso é apenas "segurança através da obscuridade"?
Desculpe se eu estou colocando as perguntas muito grossas, a curiosidade acabou de me superar. Sinta-se à vontade para responder a uma ou todas as minhas perguntas (ou diga que minhas suposições estão completamente erradas). :)
SecureString
não é realmente uma string segura. É apenas uma maneira de diminuir a janela de tempo em que alguém pode inspecionar sua memória e obter com êxito os dados confidenciais. Isso não é à prova de balas e não era para ser. Mas os pontos que você está levantando são muito válidos. Relacionados: stackoverflow.com/questions/14449579/...