Como disse no post sobre acesso ao Certificate Store do Windows com C#, o Certificate Store é um repositório centralizado onde são armazenados os certificados digitais disponíveis em um computador. É possível acessar esse repositório visualmente, acessando o console de gerenciamento pela opção Executar do menu Iniciar do Windows. Na caixa de edição que se abre, digite o comando abaixo:
Com essa aplicação, é possível gerenciar os certificados instalados no computador, fazendo a importando de novos certificados e eliminando aqueles que não são mais desejados. Observe que o painel à esquerda mostra uma organização hierárquica, com uma raiz e diversas pastas embaixo dela. O nó raiz nesse exemplo apresenta o nome Certificates - Current User. Isso significa que todas as pastas sob ele e os certificados listados no painel à direita estão disponíveis apenas para o usuário que atualmente está logado no Windows.
As pastas servem para agrupar os certificados por semelhança na finalidade de uso. Na imagem, a pasta Personal está selecionada, permitindo-nos visualizar à direita os certificados catalogados para uso pessoal do usuário Windows atual. Outro exemplo de pasta é a que contém certificados identificando as Autoridades Certificadoras (CA), que são as entidades responsáveis pela emissão dos certificados.
Do ponto de vista do programador que vai acessar o Store usando a classe X509Store (ou o CAPICOM), essas duas informações - nó raiz e pasta - são imprescindíveis. O construtor da X509Store aceita como parâmetros o Store Name e o Store Location, sendo que o name corresponde à "pasta" onde está o certificado e location é o nó raiz ao qual a pasta está atrelada. A pasta personal é mapeada com o nome "My" para essa função.
Agora, imagine que você construiu um serviço que acessa o Certificate Store. No Windows, cada serviço é executado por um usuário específico que é configurado na guia Log On das propriedades do serviço. Com isso, ele poderá entrar em execução mesmo que ninguém esteja logado no Windows pois o login será feito automaticamente para o usuário que foi associado ao serviço. Portanto, se você importou um certificado para seu usuário mas está executando o serviço com um usuário diferente, esse outro usuário não enxergará o seu certificado.
Isso vale também para aplicações ISAPI - sites construídos em ASP ou ASP.NET se encaixam nessa categoria - uma vez que elas rodam como parte do serviço do IIS (Internet Information Services). O IIS é atrelado normalmente a um usuário padrão do Windows chamado Local System, significando que as credencias desse usuário é que serão utilizadas para acessar os recursos do sistema, tais como o registry e a hierarquia de certificados.
Para resolver esse impasse, podemos importar o certificado num Store Location acessível por todos os usuários. Como a aplicação disponível carrega apenas originalmente o Location "Current User", teremos que adicionar na mão um plugin para o Location com a característica que precisamos. Esse Location é o "Local Computer".
Para isso, execute o MMC.exe sem parâmetros no Iniciar -> Executar do Windows. No menu File da aplicação, clique na opção Add/Remove snap-in e então o botão "Add" para ativar a tela de adição dos plugins. Na lista de plugins que aparece, selecione certificates e novamente clique em "Add". A imagem abaixo mostra a tela de adição do plugin de gerenciamento de certificados com a opção "Computer Account" (o computer local) selecionada.
Após a adição, o console mostrará uma hierarquia similar à da imagem no início deste post, com a exceção de que o nó raiz será "Local Computer". Agora podemos importar certificados na pasta "Personal" e torná-los disponíveis para os programas, independentemente das credenciais do usuário que está executando esse programa ou serviço.
Certificados importados na pasta "Personal" do "Local Computer" podem, então, ser acessados abrindo-se o Certificate Store com os parâmetros mostrados abaixo:
X509Store lStore = new X509Store (StoreName.My, StoreLocation.LocalComputer);
/* ... */
/* ... */
5 comentários :
Olá Luis, Veja se você pode me ajudar.
Fiz os passos sugeridos e pelo MMC vejo o meu certificado instalado, tenho que salvar? Tenho que importar?
Fiz o seguinte:
Dim store As New X509Store(StoreName.My, StoreLocation.LocalMachine)
Dim x509 As X509Certificate2 = Nothing
Dim Key As New RSACryptoServiceProvider()
store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
Dim collection As X509Certificate2Collection = CType(store.Certificates, X509Certificate2Collection)
Dim fcollection As X509Certificate2Collection = CType(collection.Find(X509FindType.FindByTimeValid, DateTime.Now, False), X509Certificate2Collection)
Dim scollection As X509Certificate2Collection = X509Certificate2UI.SelectFromCollection(fcollection, Titulo, "Select a certificate from the following list to get information on that certificate", X509SelectionFlag.MultiSelection)
Na ultima linha esta apresentando o erro: The current session is not interactive
Minha aplicação esta em Asp.net
Desde já agradeço
Fábio
A função SelectFromCollection do X509Certificate2UI apresenta uma caixa de diálogo para que o usuário escolha um dos certificados da coleção.
Como seu código é parte de um programa Asp.NET, ele será executado no servidor, tornando impossível a interação com o usuário. Além disso, o IIS é um serviço do Windows e, como ele funciona sem interface gráfica, não faz sentido ele interagir com o usuário.
[]s.
Olá Luís, Obrigado pela atenção,
Pensei que fazendo a alteração acima resolveria meu problema, e que problema, estou pesquisando muito sobre o assunto e vejo que tem muita gente batendo cabeça.
Já cheguei a abrir o reposítório com Capicom e javascript, mas não consegui progredir, tenho a minha classe de assinatura pronta no Asp.net, pensei algo como copiar os dados para dentro da coleção X509Certificate2. seria possivel?
Abcs
Fábio
Nunca trabalhei com o cenário onde é preciso enviar para o servidor um certificado existente no navegador.
Mas fiz uma pesquisa rápida e me pareceu que o próprio navegador inclui tais informações quando envia uma requisição ao servidor. Dê uma olhada na propriedade ClientCertificate da variável Request de sua página ASP.Net.
Não fui a fundo na pesquisa pra levantar se há pré requisitos necessários para que o certificado seja incluído na requisição ...
[]s
Olá Fábio,
Também estou com o mesmo problema.Já fiz muitas coisas:
- Exportei o pfx para base64, converti para byte[] e importei para um X509Certificate. Não funciona: 403 - forbiden.
Fiz o mesmo com a classe X509Certificate2Collection, e .... nada.
A idéia é colocar todos os dados do certificado no servidor e importar para um X509, mas só funciona na máquina local. Talvez se vc tiver acesso ao servidor (eu não tenho, é terceirizado) seja possivel configurar o IIS, como ocorre com as SEFAZs, que abrem normalmente o store de certificados da máquina cliente.
abr,
Manoel Emygdio.
Postar um comentário
OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.
Observação: somente um membro deste blog pode postar um comentário.