Verificação DSIG XML
-
12-09-2019 - |
Pergunta
eu digitalmente vou assinar um documento XML e verificando-lo em 2 máquinas diferentes (assiná-lo em uma máquina e verificar em outro).
Eu estou fazendo o seguinte para verificar o DSIG XML em CSharp.Net.
public static Boolean VerifyXml(XmlDocument document)
{
document.PreserveWhitespace = true;
// Create a new CspParameters object to specify
// a key container.
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
// Create a new RSA signing key and save it in the container.
//**Earlier was getting exception here in rsaKey object**
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(document);
// Find the "Signature" node and create a new
// XmlNodeList object.
// It's guaranteed that there's always exists a signature
XmlNodeList nodeList = document.GetElementsByTagName("Signature");
// Load the <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
bool isDone = signedXml.CheckSignature(rsaKey); //**This is returning false.**
return isDone;
}
Inicialmente eu estava ficando exceção PermissionDenied quando minhas tentativas de aplicação web para acessar o contêiner de chave. No entanto eu tenho temporariamente adicionar o usuário do aplicativo e de usuário do IIS à função de Administrador e atribuído política de segurança FullTrust à minha aplicação web usando Caspol.
Q1: [A minha primeira pergunta é qual é a melhor maneira de chegar ao longo deste] ?? Eu sei que a atribuição de FullTrust aplicação web e adicionar o usuário a função de administrador não é uma idéia brilhante, mesmo que ele funciona
A minha segunda pergunta é sobre o signedXml.CheckSignature(rsaKey);
retornar false. Agora de acordo com o meu entendimento, uma vez que o documento XML é assinado digitalmente em uma máquina diferente do MAC usado para assinar ele é armazenado em que as máquinas CHAVE Container Name "XML_DSIG_RSA_KEY", mas quando eu tentei verificar a assinatura na máquina host um MAC diferente é gerada e armazenada no nome do contêiner "XML_DSIG_RSA_KEY" na máquina host, não foi verificada, portanto, a assinatura digital.
Q2: Esta suposição é correta ?? e qual é a melhor maneira de lidar com isso ... Devo usar um certificado para assinado digitalmente o documento XML e, em seguida, verificar que, nesse caso. deveria eu preciso para acompanhar o certificado com o documento XML DSIG. ???
Solução
Para responder à sua segunda pergunta primeiro: Você deseja verificar o XML com o parte pública da chave par-RSA que foi usado para assinar. Então, você precisa ou já possuir (e confiança) a chave pública na máquina verificação ou para enviar o certificado que contém a chave pública com o XML (ele pode ser armazenado dentro da estrutura da assinatura XML) e, em seguida, verificar se o certificado foi emitido por uma autoridade de certificação confiável.
Para implementar o primeiro caso, você pode chamar ToXmlString(false)
na tecla no lado de envio, armazenar o resultado em um arquivo e manter este arquivo no lado receptor. Em seguida, no fim de recepção, ler o arquivo e chamada:
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
rsaKey.ImportFromXml(publicKeyFromFile);
O segundo caso pode ser feito mediante a obtenção de um certificado, e adicioná-lo à assinatura do lado da assinatura assim:
KeyInfo keyInfo = new KeyInfo();
X509Certificate cert = // load certificate
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
Se o certificado é confiável, você pode então verificar a assinatura no lado de recebimento por apenas chamando:
bool isDone = signedXml.CheckSignature();
Para responder à sua primeira pergunta:., Uma vez que não estão mais tentando acessar o armazenamento de chave privada (que você estava fazendo, chamando o RSACryptoServiceProvider-construtor como você fez), você deve ser capaz de funcionar sem confiança total