Certificados: Não é possível encontrar o certificado e a chave privada para descriptografia Erro ao assinar
Eu trabalho na empresa com muitos servidores e PCs para desenvolvedores. Servidores são win2003, desenvolvedores de PCs com Windows XP.
Em um servidor Win2003 chamado preiis01, no ambiente de pré-produção, outras pessoas na empresa instalam um certificado de cliente usando qualquer outro usuário (domainCompany \ adminsystems) para efetuar login no servidor preiis01.
Qualquer administrador usa o usuário "domainCompany \ adminsystems" para fazer logon no servidor preiis01 (usando o Terminal Server, a Área de Trabalho Remota para Windows XP).
o usuário administrador é domainCompany \ adminsystems ", que instala o certificado.
Usuário administrador, instale-o assim:
O login da sessão como "domainCompany \ adminsystems" é um arquivo PFX. Instale o PFX e use o Assistente. A chave privada não verifica a exportação. Digite a senha e instale.
Há um aplicativo na Web que AppPool Identity é: conta NETWORK SERVICE.
servidor da web é o IIS 6.0.
em preiis01,
Esse usuário administrador executa mmc -> Snap in -> Certificates for Local Machine. No nó -> Pessoal -> Certificados, ele havia visto o certificado do cliente:
Emitido para ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SOBRENOME1 NOME1
Emitido por FNMT Clase 2 CA
Nas propriedades do certificado, a impressão digital: "93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13"
Esse usuário administrador executa estes comandos:
winhttpcertcfg.exe LOCAL_MACHINE \ My -s "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SOBRENOME1 NAME1" -g -a "SERVIÇO DE REDE"
O resultado é:
Certificado correspondente:
CN = ENTIDAD COMPANY SEGURE SA - CIF A93 - NOMBRE SOBRENOME1 NOME1
OU = 703015476
OU = CA do FNMT Clase 2
O = FNMT
C = ES
Concedendo acesso à chave privada para a conta: NT AUTHORITY \ NETWORK SERVICE
Agora, o usuário admin executa este comando:
winhttpcertcfg.exe -l -c LOCAL_MACHINE \ My -s "ENTIDAD COMPANY INSURE SA - CIF A93 - NOME SOBRENOME1 NOME1"
O resultado é:
Certificado correspondente:
CN = ENTIDAD COMPANY SEGURE SA - CIF A93 - NOMBRE SOBRENOME1 NOME1
OU = 700012476
OU = CA do FNMT Clase 2
O = FNMT
C = ES
Contas e grupos adicionais com acesso à chave privada incluem: domainCompany \ adminsystems NT AUTHORITY \ SYSTEM BUILTIN \ Administrators NT AUTHORITY \ NETWORK SERVICE
Agora, em uma página aspx no aplicativo Web no servidor Win2003, IIS 6.0, eu tenho este código:
NOte: o valor para X509Certificate2.HasPrivateKeyAccess () é NO (false) para o certificado "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE NOME1 NOME1".
Aplicativo ASP.NET é executado usando a identidade :: NT AUTHORITY \ NETWORK SERVICE
lbInfo.Text += "<br/><br/>ASP.NET application executes using the identity :: <b>" + WindowsIdentity.GetCurrent().Name + "</b><br>";
var store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
Certificates = store.Certificates;
repeater1.DataSource = Certificates;
repeater1.DataBind();
var nombreCertificado = "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1";
store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySubjectName, nombreCertificado, false);
if (col.Count > 0)
{
X509Certificate2 certificate = col[0];
store.Close();
Message.Text = "Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;
FirmarConCertificado(nombreCertificado, certificate);
}
else
{
store.Close();
Message.Text = "El certificado " + nombreCertificado + " no esta instalado en la máquina";
}
public void FirmarConCertificado(string nombreCertificado, X509Certificate2 certificate)
{
try
{
var mensaje = "Datos de prueba";
System.Text.Encoding enc = System.Text.Encoding.Default;
byte[] data = enc.GetBytes(mensaje);
var contentInfo = new System.Security.Cryptography.Pkcs.ContentInfo(data);
var signedCms = new System.Security.Cryptography.Pkcs.SignedCms(contentInfo, true);
var cmsSigner = new System.Security.Cryptography.Pkcs.CmsSigner(certificate);
// Sign the CMS/PKCS #7 message
signedCms.ComputeSignature(cmsSigner);
// Encode the CMS/PKCS #7 message
var ret = Convert.ToBase64String(signedCms.Encode());
Message.Text += "Firmado con Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;
}
catch (Exception ex)
{
Message.Text = "Error al firmar con certificado: " + ex.ToString();
Message.Text += "<br /><br />InnerException: " + ex.InnerException;
}
}
O código falha para mim e recebo este erro: Não é possível encontrar o certificado e a chave privada para descriptografia.
A linha de erro é: assinadoCms.ComputeSignature (cmsSigner);
Erro no firmar com certificado: System.Security.Cryptography.CryptographicException: Não foi possível encontrar o certificado e a chave privada para descriptografia.
em System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo (assinante CmsSigner, silencioso booleano) em System.Security.Cryptography.Pkcs.SignedCms.Sign (signatário CmsSigner, silencioso booleano) em System.Security.Cryptography.Pkcs.SignedCms.Comp (Signatário CmsSigner, silencioso booleano) em System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature (signatário CmsSigner) em ASP.dgsfp_test_testcert_aspx.FirmarConCertificado (String nombreCertificado, certificado X509Certificate2) em c: \ Company \ App \ Test \ Test \ Test. linha 242
Em seguida, o usuário administrador (lembro-me, que instala o certificado) executa estes comandos:
FindPrivateKey My LocalMachine -t "93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13" –c
FindPrivateKey My LocalMachine -n "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SOBRENOME1 NOME1" - a
FindPrivateKey My LocalMachine -n "CN = ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SOBRENOME1 NOME1" –a
O resultado para todos os 3 comandos é o mesmo:
FindPrivateKey ajuda o usuário a encontrar o local do arquivo de Chave Privada de um Certificado X.50 9.
Uso: FindPrivateKey [{{-n} | {-t}} [-f | -d -uma]]
nome do sujeito do certificado
impressão digital do certificado (use certmgr.exe para obtê-lo)
-f somente nome do arquivo de saída
somente diretório de saída -d
-um nome de arquivo absoluto de saída p. FindPrivateKey My CurrentUser -n "CN = John Doe"
por exemplo. FindPrivateKey My LocalMachine -t "03 33 98 63 d0 47 e7 48 71 33 62 64 76 5 c 4c 9d 42 1d 6b 52" -c
FindPrivateKey não recebe nada, mas winhttpcertcfg.exe -l funciona bem (certificado correspondente)
Atribuímos privilégios ao usuário do Serviço de Rede usando a ferramenta winhttpcertcfg.exe e, no código ASP.NET (executado na conta do Serviço de Rede), o certificado foi encontrado. Mas falha ao assinar usando o certificado.
Se alguém puder nos fornecer algumas informações ou sugestões
atualizar:
Usuário no domínio "domainCompany \ Pre_Certificado" instala o Certificado no Store Local Machine.
domainCompany \ Pre_Certificado é Administrator, no grupo IIS_WPG, possui Políticas Locais: "Log on as Service"
Eu configuro a Identidade do AppPool no IIS 6.0 para: domainCompany \ Pre_Certificado
O aplicativo ASP.NET é executado usando a identidade :: domainCompany \ Pre_Certificado
Reciclo o AppPool e executo o aplicativo, recebo System.Security.Cryptography.CryptographicException: Não é possível encontrar o certificado e a chave privada para descriptografia
Se eu testar novamente, efetue login na sessão no servidor IIS, usando o domínio domain Company \ Pre_Certificado, chamo a página no aplicativo ASP.NET e tudo está OK.
(observação: faça logon no servidor IIS usando o Terminal Server)
Mas se a sessão de logoff no servidor IIS (usuário: domainCompany \ Pre_Certificado), eu recebo o mesmo erro:
System.Security.Cryptography.CryptographicException: Não foi possível encontrar o certificado e a chave privada para descriptografia
Alguma sugestão ??