/// <summary> /// Assina Multiplos elementos dentro da Xml. /// </summary> /// <param name="xml">O Xml.</param> /// <param name="docElement">O elemento principal do xml a ser assinado.</param> /// <param name="infoElement">O elemento a ser assinado.</param> /// <param name="certificado">O certificado.</param> /// <param name="comments">Se for <c>true</c> vai inserir a tag #withcomments no transform.</param> /// <param name="digest">Algoritmo usando para gerar o hash por padrão SHA1.</param> /// <returns>System.String.</returns> /// <exception cref="ACBrDFeException">Erro ao efetuar assinatura digital.</exception> /// <exception cref="ACBrDFeException">Erro ao efetuar assinatura digital.</exception> public static string AssinarXmlTodos(string xml, string docElement, string infoElement, X509Certificate2 certificado, bool comments = false, SignDigest digest = SignDigest.SHA1) { try { var doc = new XmlDocument(); doc.LoadXml(xml); var xmlElements = doc.GetElementsByTagName(docElement).Cast <XmlElement>() .Where(x => x.GetElementsByTagName(infoElement).Count == 1).ToArray(); Guard.Against <ACBrDFeException>(!xmlElements.Any(), "Nome do elemento de assinatura incorreto"); foreach (var element in xmlElements) { var xmlDoc = new XmlDocument { PreserveWhitespace = true }; xmlDoc.LoadXml(element.OuterXml); AssinarDocumento(xmlDoc, docElement, infoElement, "Id", certificado, comments); // ReSharper disable once AssignNullToNotNullAttribute var signedElement = doc.ImportNode(xmlDoc.DocumentElement, true); element.ParentNode?.ReplaceChild(signedElement, element); } return(doc.AsString()); } catch (Exception ex) { throw new ACBrDFeException("Erro ao efetuar assinatura digital.", ex); } }
private static string GetSignatureMethod(SignDigest digest) { return(digest switch { SignDigest.SHA1 => "http://www.w3.org/2000/09/xmldsig#rsa-sha1", SignDigest.SHA256 => "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", _ => throw new ArgumentOutOfRangeException(nameof(digest), digest, null) });
private static string GetDigestMethod(SignDigest digest) { switch (digest) { case SignDigest.SHA1: return("http://www.w3.org/2000/09/xmldsig#sha1"); case SignDigest.SHA256: return("http://www.w3.org/2001/04/xmlenc#sha256"); default: throw new ArgumentOutOfRangeException(nameof(digest), digest, null); } }
/// <summary> /// Assina a XML usando o certificado informado. /// </summary> /// <param name="xml">O Xml.</param> /// <param name="docElement">O elemento principal do xml a ser assinado.</param> /// <param name="infoElement">O elemento a ser assinado.</param> /// <param name="pCertificado">O certificado.</param> /// <param name="comments">Se for <c>true</c> vai inserir a tag #withcomments no transform.</param> /// <param name="digest">Algoritmo usando para gerar o hash por padrão SHA1.</param> /// <returns>System.String.</returns> /// <exception cref="ACBrDFeException">Erro ao efetuar assinatura digital.</exception> /// <exception cref="ACBrDFeException">Erro ao efetuar assinatura digital.</exception> public static string AssinarXml(string xml, string docElement, string infoElement, X509Certificate2 pCertificado, bool comments = false, SignDigest digest = SignDigest.SHA1) { try { var xmlDoc = new XmlDocument { PreserveWhitespace = true }; xmlDoc.LoadXml(xml); AssinarDocumento(xmlDoc, docElement, infoElement, "Id", pCertificado, comments); return(xmlDoc.AsString()); } catch (Exception ex) { throw new ACBrDFeException("Erro ao efetuar assinatura digital.", ex); } }
/// <summary> /// 发送请求 /// </summary> /// <param name="url"></param> /// <param name="api"></param> /// <param name="data"></param> /// <returns></returns> private static string SendAPI(string url, string api, string data) { string Appkey = GetAppSettingsValue("Labels_Appkey"); string Secret = GetAppSettingsValue("Labels_Secret"); LabelsCmdDto cmd = new LabelsCmdDto() { Appkey = Appkey, Data = Convert.ToBase64String(Encoding.UTF8.GetBytes(data)), Timestamp = DateTime.Now.ToString("yyyyMMddHHmmss"), }; var sign = SignDigest.SignTopRequest(cmd.GetParameters(), Secret); cmd.Sign = sign; IDictionary <string, string> parameters = new Dictionary <string, string>(cmd.GetParameters()); parameters.Add("Sign", cmd.Sign); WebUtils webUtils = new WebUtils(); var resultStr = webUtils.DoPost(url + api, parameters); return(resultStr); }
/// <summary> /// Assina o xml. /// </summary> /// <param name="certificado">Certificado digital</param> /// <param name="options">Options.</param> /// <param name="comments">if set to <c>true</c> [comments].</param> /// <param name="digest">Digest.</param> protected void AssinarDocumento(X509Certificate2 certificado, SaveOptions options, bool comments, SignDigest digest) { Signature = SigningManager.AssinarDocumento(this, certificado, comments, digest, options, out var xml); Xml = xml; }
/// <summary> /// Assina a XML usando o certificado informado. /// </summary> /// <param name="xml">O Xml.</param> /// <param name="docElement">O elemento principal do xml a ser assinado.</param> /// <param name="infoElement">O elemento a ser assinado.</param> /// <param name="certificado">O certificado.</param> /// <param name="comments">Se for <c>true</c> vai inserir a tag #withcomments no transform.</param> /// <param name="identado">Se for <c>true</c> irá retornar o xml identado.</param> /// <param name="showDeclaration">Se for <c>true</c> irá incluir a declaração no xml</param> /// <param name="digest">Algoritmo usando para gerar o hash por padrão SHA1.</param> /// <returns>System.String.</returns> /// <exception cref="VipException">Erro ao efetuar assinatura digital.</exception> public static string AssinarXml(string xml, string docElement, string infoElement, X509Certificate2 certificado, bool comments = false, bool identado = false, bool showDeclaration = true, SignDigest digest = SignDigest.SHA1) { try { var xmlDoc = new XmlDocument { PreserveWhitespace = true }; xmlDoc.LoadXml(xml); AssinarDocumento(xmlDoc, docElement, infoElement, "Id", certificado, comments, digest); return(xmlDoc.AsString(identado, showDeclaration)); } catch (System.Exception ex) { throw new VipException("Erro ao efetuar assinatura digital.", ex); } }
private static XmlElement GerarAssinatura(XmlDocument doc, string infoElement, string signAtribute, X509Certificate2 certificado, bool comments, SignDigest digest) { Guard.Against <ArgumentException>(!infoElement.IsNullOrEmpty() && doc.GetElementsByTagName(infoElement).Count != 1, "Referencia invalida ou não é unica."); //Adiciona Certificado ao Key Info var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificado)); //Seta chaves var signedDocument = new SignedXml(doc) { SigningKey = certificado.PrivateKey, KeyInfo = keyInfo, SignedInfo = { SignatureMethod = GetSignatureMethod(digest) } }; var uri = infoElement.IsNullOrEmpty() || signAtribute.IsNullOrEmpty() ? "" : $"#{doc.GetElementsByTagName(infoElement)[0].Attributes?[signAtribute]?.InnerText}"; // Cria referencia var reference = new System.Security.Cryptography.Xml.Reference { Uri = uri, DigestMethod = GetDigestMethod(digest) }; // Adiciona transformação a referencia reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigC14NTransform(comments)); // Adiciona referencia ao xml signedDocument.AddReference(reference); // Calcula Assinatura signedDocument.ComputeSignature(); // Pega representação da assinatura return(signedDocument.GetXml()); }
/// <summary> /// Gera a assinatura do xml e retorna uma instancia da classe <see cref="DFeSignature" />. /// </summary> public static DFeSignature AssinarDocumento <TDocument>(this DFeSignDocument <TDocument> document, X509Certificate2 certificado, bool comments, SignDigest digest, SaveOptions options, out string signedXml) where TDocument : class { Guard.Against <ArgumentException>(!typeof(TDocument).HasAttribute <DFeSignInfoElement>(), "Atributo [DFeSignInfoElement] não encontrado."); var xml = document.GetXml(options, Encoding.UTF8); var xmlDoc = new XmlDocument { PreserveWhitespace = true }; xmlDoc.LoadXml(xml); var signatureInfo = typeof(TDocument).GetAttribute <DFeSignInfoElement>(); var xmlSignature = GerarAssinatura(xmlDoc, signatureInfo.SignElement, signatureInfo.SignAtribute, certificado, comments, digest); // Adiciona a assinatura no documento e retorna o xml assinado no parametro signedXml var element = xmlDoc.ImportNode(xmlSignature, true); xmlDoc.DocumentElement?.AppendChild(element); signedXml = xmlDoc.AsString(!options.HasFlag(SaveOptions.DisableFormatting), !options.HasFlag(SaveOptions.OmitDeclaration)); return(DFeSignature.Load(xmlSignature.OuterXml)); }
/// <summary> /// Assina o xml informado. /// </summary> /// <param name="doc">O Xml</param> /// <param name="docElement">O elemento principal do xml a ser assinado.</param> /// <param name="infoElement">O elemento a ser assinado.</param> /// <param name="signAtribute">O atributo identificador do elemento a ser assinado.</param> /// <param name="certificado">O certificado.</param> /// <param name="comments">Se for <c>true</c> vai inserir a tag #withcomments no transform.</param> /// <param name="digest">Algoritmo usando para gerar o hash por padrão SHA1.</param> /// <returns>System.String.</returns> /// <exception cref="VipException">Erro ao efetuar assinatura digital.</exception> public static void AssinarDocumento(XmlDocument doc, string docElement, string infoElement, string signAtribute, X509Certificate2 certificado, bool comments = false, SignDigest digest = SignDigest.SHA1) { Guard.Against <ArgumentNullException>(doc == null, "XmlDocument não pode ser nulo."); Guard.Against <ArgumentException>(docElement.IsNullOrEmpty(), "docElement não pode ser nulo ou vazio."); var xmlDigitalSignature = GerarAssinatura(doc, infoElement, signAtribute, certificado, comments, digest); var xmlElement = doc.GetElementsByTagName(docElement).Cast <XmlElement>().FirstOrDefault(); Guard.Against <VipException>(xmlElement == null, "Elemento principal não encontrado."); var element = doc.ImportNode(xmlDigitalSignature, true); xmlElement.AppendChild(element); }
private static void AssinarDocumento(XmlDocument doc, string docElement, string infoElement, X509Certificate2 certificado, bool comments = false, SignDigest digest = SignDigest.SHA1) { Guard.Against <ArgumentException>(!infoElement.IsEmpty() && doc.GetElementsByTagName(infoElement).Count != 1, "Referencia invalida ou não é unica."); //Adiciona Certificado ao Key Info var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificado)); //Seta chaves var signedDocument = new SignedXml(doc) { SigningKey = certificado.PrivateKey, KeyInfo = keyInfo, SignedInfo = { SignatureMethod = GetSignatureMethod(digest) } }; var uri = infoElement.IsEmpty() ? "" : $"#{doc.GetElementsByTagName(infoElement)[0].Attributes?["Id"]?.InnerText}"; // Cria referencia var reference = new Reference { Uri = uri, DigestMethod = GetDigestMethod(digest) }; // Adiciona transformação a referencia reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigC14NTransform(comments)); // Adiciona referencia ao xml signedDocument.AddReference(reference); // Calcula Assinatura signedDocument.ComputeSignature(); // Pega representação da assinatura var xmlDigitalSignature = signedDocument.GetXml(); // Adiciona ao doc XML var xmlElement = doc.GetElementsByTagName(docElement).Cast <XmlElement>().FirstOrDefault(); Guard.Against <ACBrDFeException>(xmlElement == null, "Nome do docElemnt incorreto"); var element = doc.ImportNode(xmlDigitalSignature, true); xmlElement.AppendChild(element); }
/// <summary> /// Assina a XML usando o certificado informado. /// </summary> /// <param name="xml">O Xml.</param> /// <param name="docElement">O elemento principal do xml a ser assinado.</param> /// <param name="infoElement">O elemento a ser assinado.</param> /// <param name="pCertificado">O certificado.</param> /// <param name="comments">Se for <c>true</c> vai inserir a tag #withcomments no transform.</param> /// <param name="identado">Se for <c>true</c> vai identar o xml de retorno</param> /// <param name="showDeclaration">Se for <c>true</c> vai incluir a declaração do xml</param> /// <param name="digest">Algoritmo usando para gerar o hash por padrão SHA1.</param> /// <returns>System.String.</returns> /// <exception cref="ACBrDFeException">Erro ao efetuar assinatura digital.</exception> /// <exception cref="ACBrDFeException">Erro ao efetuar assinatura digital.</exception> public static string AssinarXml(string xml, string docElement, string infoElement, X509Certificate2 pCertificado, bool comments = false, bool identado = false, bool showDeclaration = true, SignDigest digest = SignDigest.SHA1) { return(AssinarXml(xml, docElement, infoElement, "Id", pCertificado, comments, identado, showDeclaration, digest)); }