OpenNFSe

OpenNFSe (http://www.opennfse.com.br/forums/index.php)
-   Ajuda sobre código fonte (http://www.opennfse.com.br/forums/forumdisplay.php?f=5)
-   -   O Conjunto de Chaves Não Existe - NFSPBH (http://www.opennfse.com.br/forums/showthread.php?t=8)

Leonardo 30/10/2009 15:09

O Conjunto de Chaves Não Existe - NFSPBH
 
Conseguir assinar esta muito dificil. Ja peguei mais de um Codigo de Assinatura em Delphi 7.
Tenho o SOAP atualizado, conforme os colegas alertaram ai.
Minha rotina de consulta a nota esta funcionando.
Mas na hora de assinar para enviar o ocorre na linha
dsigKey := xmldsig.createKeyFromCSP(PrivateKey.ProviderType, PrivateKey.ProviderName, PrivateKey.ContainerName, 0);
o seguinte erro: "O Conjunto de Chaves Não Existe"
Os dois codigos de assinatura delphi tem este comando, e o mais estranho, é que ontem peguei um codigo de assinatura com um colega,
que chegou a funcionar algumas vezes. Resolvi dar um boot na maquina porque tava dando um pau pra conectar no webservice ai nao funcionou
mais. O Programa webservicePBH que ja colocaram ai da o mesmo pau. Ja vi uma discucao aqui no forum onde um cara repassou uma mensagem que tem no site da receita que diz que quando da esta mensagem tem que reinstar o token, acho improvavel que o erro seja este. O que me deixou assombrado foi o codigo funcionar ontem, e sem que eu mechesse no codigo da ultima vez que assinou, parou de assinar e voltou a dar a referida mensagem. Meu token é A3 PRONOVA. Ate o momento eu ja usei ele no site online pra lancar uma nota teste, a qual, consigo no meu programa consultar via webservice. Nos tambem tentamos utilizar a NFSEUtil feita em .net e assinatura parecia esta legal, mas foi rejeitada com o codigo E174. Minha preferencia é tentar uma solucao apenas em Delphi 7, so tentei usar esta outra solucao por causa da mensagem "O Conjunto de Chaves nao existe". Se alguem puder dar uma luz ai agradeceria muito.
Abraco a todos os sofredores da implementacao da NFS da PBH

LuizVaz 31/10/2009 21:45

Oi Leonardo!

É o seguinte, provavelmente o Store da Microsoft está bagunçado.

Dê também um PrintScreen na Tela de Certificados do Internet Explorer:
Ferramentas/Opções da Internet/Conteúdo

http://img2.pict.com/d4/58/dd/1881960/0/certificado.png

Para resolver, basta rodar o programa da PRODEMGE para instalar as chaves no Internet Explorer.

Agora, cuidado!
Se você mexeu dentro do eToken com o aplicativo de administração, você pode ter limpado o conteúdo.
Se isso acontecer, já era o eToken.

Att,
Luiz Vaz

LuizVaz 03/11/2009 03:00

Leonardo,

Acho que isso pode resolver o seu problema.
Tem que passar corretamente os dados do certificado para a função.
Senão dá pau mesmo.

O que fiz foi apresentar a caixa de seleção do certificado para o usuário.
Depois de selecionado, basta pegar os dados do objeto Certificate.

Código:

function TfrmMain.SignXML(fwWriteKeyInfo: _XMLDSIG_WRITEKEYINFO): Boolean;
const
  sCert: array [Boolean] of string = ('s',  '');
  sDisp: array [Boolean] of string = ('is', 'l');
var
  h, i: Cardinal;
  Sett, Cert, Certs, Store: OleVariant;
  s1, s2, sProvider, sContainer: String;
  eType: CAPICOM_PROV_TYPE;
  pKey, pKeyOut: IXMLDSigKey;
  sSigs, sX509: IXMLDOMNodeList;
  sSig: IXMLDOMNode;
begin
  Try
    Sett := CoSettings.Create;
    Sett.EnablePromptForCertificateUI := True;
    Store := CoStore.Create;
    Store.Open(CAPICOM_CURRENT_USER_STORE, 'My', CAPICOM_STORE_OPEN_EXISTING_ONLY);

    //Remove os Certificados que não são Signature da lista
    Certs  := Store.Certificates;
    for i := Store.Certificates.Count downto 1 do
      begin
        Cert := IInterface(Certs.Item[i]) as ICertificate2;
        if (not Cert.HasPrivateKey) then
          Certs.Remove(i);
      end;

    Try
      Cert := Null;
      s1 := sCert[Certs.Count = 0];
      s2 := sDisp[Certs.Count = 0];
      //---> Usuário Seleciona o Certificado
      Certs := Certs.Select(Format('Certificado%s disponíve%s', [s1, s2]),
                            'Selecione o Certificado Digital para uso', FALSE);
      Cert := IInterface(Certs.Item[1]) as ICertificate2;
    Except
      on E: EOleException do
        begin
          i := e.ErrorCode;
          //---> Usuário abortou a seleção
          if i = $80880902 then
            Abort()
          else
            Raise;
        end;
    End;

    if not VarIsNull(Cert) then
    begin
      // Encopntra os <ds:Signature> nodes.
      FXMLDoc.setProperty('SelectionNamespaces', DSIGNS);
      sSigs := FXMLDoc.selectNodes('.//ds:Signature');

      if (sSigs.length = 0) then
          Exception.Create('A Tag Signature não foi encontrada no XML.');

      //É necessário ter a 1ª assinatura 
      FXMLDSig.signature := sSigs.item[0]; 
      FXMLDSig.store := Store;
      //---> Dados necessários para gerar a assinatura
      eType := Cert.PrivateKey.ProviderType;
      sProvider := Cert.PrivateKey.ProviderName;
      sContainer := Cert.PrivateKey.ContainerName;

      // assina cada TAG Signature
      for i := 0 to (sSigs.length-1) do
      begin
        // próximo <ds:Signature> DOM node.
        FXMLDSig.signature := sSigs.item[i];
        // ---> Assinatura do campo Signature do XML
        pKey := FXMLDSig.createKeyFromCSP(eType, sProvider, sContainer, 0);

        if (pKey = nil) then
          Exception.Create('Invalid key.\n');
        pKeyOut := FXMLDSig.sign(pKey, fwWriteKeyInfo);

        // deixa no KeyInfo somente um X509Data
        sX509 := FXMLDoc.selectNodes('//ds:X509Data[position() > 1]');
        if sX509.length > 0 then
          for h := (sX509.length-1) downto 0 do
          begin
            sSig := sX509.item[h].parentNode;
            sX509.item[h].text := '';
            sSig.removeChild(sX509.item[h]);
          end;           
      end;
    end;

    if (pKeyOut = nil) then
      Exception.Create('Falha durante assinatura.\n');
  finally

  end;

  Result := true;
end;

Resumindo, você está passando errado o conjunto de informações para a função createKeyFromCSP.

Qualquer coisa, pegue meu exemplo no:
http://opennfse.googlecode.com/files/NFSeSigner.zip

OBS.: Repare que usei OleVariant e não a interface em algumas variáveis.
Isso é importante, porque força o windows a usar a versão certa do Objeto na CAPICOM e XMLDOC.

Atenciosamente,
Luiz Vaz

LuizVaz 04/11/2009 21:33

Citação:

Leonardo Pereira, em 04 November 2009 - 08:54 AM, disse:
Seguem as respostas solicitadas por voce.
- Aparace o dialogo de seleção de certificado?
Sim e eu seleciono o do Token.
- Você consegue selecionar algum?
Sim, seleciono o do token.
- Você consegue entrar no site da prefeitura usando o token?
Sim, e ja inseri nota , assinei no site e consultei.
- Você está usando o Internet Explorer?
Sim e os certificados junto com a cadeia de certificados estao instalados
- Quando você comprou o certificado quem configurou, a PRODEMGE?
SERPRO, é o que vem no certificado.
Senão qual o site para consulta?
SERPRO
- Você averigou que as chaves não foram apagadas do token?
Sim, se fossem apagadas o token nao funcionaria no site on line.

É interessante que todo mundo que eu converso aqui do forum so ta usando A1. Gostaria de saber se este codigo funciona mesmo no A3, porque não acredito que o createKeyFromCSP funcione com o Token A3. Eu ja vi aqui no forum outra péssoa que teve o mesmo erro que eu "O Conjunto de Chaves nao existe" e pelo que vi ninguem soube onde estava a solucao. Acho que voces devem testar o Token A3, pois algum cliente de voces usarão o A3.
A minha aplicacao delphi consegue acessar o metodo de consulta a nota no webservice da preveitura e volta o xml blz, o problema é assinar, que nao consigo.
Antes de atualizar meu soap no delphi 7 o xml nem chegava la e ja dava uma mensagem, tipo um showmessage, de erro. Mas o soap ja atualizei ha muitos dias e entao a consulta do xml retorna correta. Eu tive um pouco de dificuldade para ajustar o xml de retorno usando o mapper xml. O problema acontece quando vem notas canceladas junto com notas notas normais. O xml vem beleza , mas fico sem saber como tratar o arquivo de transform. Mas isto é de menos. O que ta me deixando sem dormir é o problema de assinar o token A3. Gostaria de Saber aqui neste forum quem consegue utilizar Delphi 7 Soap com token A3. Porque todo que diz que o codigo funciona usa A1.

quanto a sua orientacao nao entedi para que e onde usar. Quais screenshots e onde colocar e pra que ? Desculpa mas esta orientacao fiquei boiando...
Use o site Image hosting, picture hosting, photo hosting and photo sharing at Pict para colocar as Screenshots.
Abracos,
Leo.

Ok,

Bom, Eu uso o A3 e a questão na verdade é o tipo e modelo do A3.
A3 é na verdade um Token onde a chave privada não é revelada.
O processo de assinatura é feita pelo hardware do Token.
O meu é eToken da Alladin.
Esse é o eToken oficial da PRODEMGE.

Cada Token tem sua API de implementação.
A CAPICOM da microsft faz a mediação.

Para saber qual dll seu token registra use o PKCS11Explorer.
Caso ainda não tenha acessado o site da Sarah Dean, baixe ele:
http://www.sdean12.o...Explorer100.zip

De inicio ele já encontra uma DLL se ela for conhecida.
Exemplo do meu eToken: eTPKCS11.dll

Aí você dá load e se seu Token estiver ativo ele te mostra e permite você fazer o login.
Após fazer o LOGIN você pode visualizar os seus dados.
Cuidado para não fazer nada de errado ou adeus TOKEN.

Para usar o PKCS11 no SOAP do Delphi o pessoal utiliza a função da WinINET:
InternetSetOption passando com INTERNET_OPTION_CLIENT_CERT_CONTEXT o contexto do certificado.
O Windows faz o resto, resumindo, faz sozinho o papel da createKeyFromCSP.
Isso quer dizer que você precisa do Internet Explorer 6 ou superior, senão não funciona.
E isso quer dizer também que essa função vai verificar o que está salvo no Internet Explorer sobre seus certificados.

A createKeyFromCSP é da CAPICOM que por sua vez usa a CryptoAPI do Windows, que por sua vez usa a Cryptoki do Token.

Você pode entender isso aqui:
How To Select Client Certificate in WinInet
http://www.rsa.com/r...ode.asp?id=2133


O que está acontecendo então é que a rotina não está conseguindo achar os valores corretos nas linhas:
eType := Cert.PrivateKey.ProviderType;
sProvider := Cert.PrivateKey.ProviderName;
sContainer := Cert.PrivateKey.ContainerName;

Depure e poste os valores exatos dessas váriaveis.

Quanto ao pict.com era para você dar print na tela de certificados do Internet Explorer.
Na sessão de Chaves Pessoais.
Ou então no snapin: certmgr.msc assim:

http://img2.pict.com/cc/09/a3/1915081/0/nfse11.png

Atenciosamente,
Luiz Vaz

LuizVaz 04/11/2009 21:42

Opa,

acho que encontrei algo:
microsoft.public.platformsdk.security: Re: Keyset does not exist

Verifique as permissões da pasta:
'C:\Documents and Settings\UserName\Application Data\Microsoft\Crypto\RSA'
na máquina com problema.

Se for português é:
'C:\Documents and Settings\UserName\Dados de aplicativos\Microsoft\Crypto\RSA'

Pode ser que foi alterado e você tenha que colocar novamente o criador do certificado como owner.

Lembrando que a chave é por usuário no modo que eu coloquei.
Por isso a linha:

Código:

  Store.Open(CAPICOM_CURRENT_USER_STORE, 'My', CAPICOM_STORE_OPEN_EXISTING_ONLY);
Dê uma olhada se o Certificado está salvo no SystemCertificates em:
HKEY_CURRENT_USER\Software\Microsoft\SystemCertifi cates\My\PhysicalStores

Atenciosamente,
Luiz Vaz

Leonardo 06/11/2009 17:31

Sua Orientacao sobre a atualizacao do software do token A3 Pronova
"O seu token é o ePass2000_FT12.
E ele usa o Middleware ePassNG Multi-platform para Microsoft CSP e PKCS#11 v2.11.
Pelo visto o pessoal da Pronova só te passou o ePass2000_FT12 Windows Redistributable Package v1.1.

Baixe o ePass2000_FT12 Windows Middleware v1.18 usando esse link:
http://www.mediafire...eware_V1.18.zip
O site oficial tem que fazer login e é muito lento.
Então já fiz o download e coloquei no mediafire.
OBS.: A senha é rockey.
"
PARABENS !
Apos esta saga para descobrir o problema do token da Pronova, voce acertou em cheio.
Atualizei o software do token da PRONOVA e esta assinando corretamente. Ja consegui mandar 1 nota pra prefeitura que foi aceita pelo webservice.
Gostaria de ressaltar minha INDIGNACAO para com a empresa MAXDATA, de onde compramos o token ha menos de 1 mes, vindo o software da PRONOVA,que
controla o token , desatualizado, causando um ENORME transtorno, que era a mensagem "O Conjuntos de chaves nao existe" no momento da assinatura,
atravez da chamada do metodo CreateKeyFromCSP. Acho que voce ficara mais aliviado sabendo que este token A3 funciona para assinatura da NFS PBH.
Mais uma vez minha gratidão por seu empenho em resolver este problema. Muito obrigado !!!

LuizVaz 07/11/2009 00:28

Hehehe,

Esses tokens só dão trabalho...
O problema é que o pessoal não aprende.
Eles só querem vender, depois o usuário que se vire.

O pior é que nem eles sabem.
Como vão dar suporte? :confused:

Esse é o objetivo dessa comunidade:
Temos que juntar forças e conhecimento para evitar esses erros bobos. :D

Att,
Luiz Vaz


Horários baseados na GMT -2. Agora são 21:29.

vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.3.0