/// <summary> /// Метод подписи данных /// </summary> /// <param name="data"></param> /// <param name="thumbprint"></param> /// <returns></returns> public byte[] Sign(byte[] data, string thumbprint) { if (SignServiceUtils.IsUnix) { var unixService = new SignServiceUnix(loggerFactory); return(unixService.Sign(data, thumbprint)); } else { var winService = new SignServiceWin(loggerFactory); return(winService.Sign(data, thumbprint)); } }
/// <summary> /// Метод подписания вложений подписью органа власти /// </summary> /// <param name="doc"></param> /// <param name="certificate"></param> /// <returns></returns> private XmlDocument SignAttachmentsOv(XmlDocument doc, IntPtr certificate) { XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); string prefix = FindPrefix(doc.DocumentElement, true); nsmgr.AddNamespace(prefix, NamespaceUri.Smev3TypesBasic); log.LogDebug($"Пытаемся найти тэг заголовка вложений."); string findHeaderString = string.Format("//{0}:AttachmentHeaderList", prefix); XmlElement attachmentHeaderList = doc.SelectSingleNode(findHeaderString, nsmgr) as XmlElement; log.LogDebug($"Пытаемся найти тэг с контентом вложений."); string findContentString = string.Format("//{0}:AttachmentContentList", prefix); XmlElement attachmentContentList = doc.SelectSingleNode(findContentString, nsmgr) as XmlElement; if (attachmentHeaderList != null && attachmentContentList != null) { log.LogDebug("Список заголовков и контента с вложениями был успешно получен."); bool changed = false; AttachmentHeaderList headerList = null; try { log.LogDebug("Пытаемся получить объект AttachmentHeaderList."); headerList = DeserializeXml <AttachmentHeaderList>(attachmentHeaderList, NamespaceUri.Smev3TypesBasic); log.LogDebug("Объект AttachmentHeaderList успешно получен."); } catch (Exception ex) { throw new Exception($"Ошибка при получении объекта AttachmentHeaderList. {ex.Message}."); } // Если нет информации о вложениях if (headerList == null || headerList.AttachmentHeader == null || headerList.AttachmentHeader.Length <= 0) { log.LogDebug("Вложения для подписи не найдены."); return(doc); } // Проверим есть ли вложения для которых необходима подпись log.LogDebug("Проверим есть ли вложения для которых необходима подпись."); var needSigned = false; foreach (var header in headerList.AttachmentHeader) { if (header.SignaturePKCS7 == null || header.SignaturePKCS7.Length <= 0) { log.LogDebug($"Вложение {header.contentId} нуждается в подписи."); needSigned = true; break; } } // Если все вложения уже подписаны, выходим if (!needSigned) { log.LogDebug("Все вложения являются подписанными."); return(doc); } // Пытаемся получить список контента вложений. Обрабатывает только вложения указанные в XML в виде base64 строки, для случаев с // расположением вложения на FTP или в случае если данный XML является частью МТОМ запроса предполагается что вложения были подписаны отдельно, заранее AttachmentContentList contentList = null; try { contentList = DeserializeXml <AttachmentContentList>(attachmentContentList, NamespaceUri.Smev3TypesBasic); } catch (Exception ex) { throw new Exception($"Ошибка при десериализации контента вложений. " + $"Убедитесь, что для вложений, которые находятся на FTP, или будут расположены в МТОМ запросе подпись была получена отдельно. " + $"Содержимое ошибки {ex.Message}."); } if (contentList != null && contentList.AttachmentContent != null && contentList.AttachmentContent.Length > 0) { foreach (AttachmentHeaderType header in headerList.AttachmentHeader) { if (header.SignaturePKCS7 == null || header.SignaturePKCS7.Length == 0) { log.LogDebug($"В заголовке вложения отсутствует подпись. Пытаемся подписать."); AttachmentContentType content = contentList.AttachmentContent.FirstOrDefault(cnt => cnt.Id == header.contentId); if (content != null && content.Content != null && content.Content.Length > 0) { byte[] signature = null; try { if (SignServiceUtils.IsUnix) { log.LogDebug($"Выполняем подпись под Unix платформой."); signature = SignServiceUnix.Sign(content.Content, certificate); } else { log.LogDebug($"Выполняем подпись под Windows платформой."); signature = SignServiceWin.Sign(content.Content, certificate); } } catch (Exception ex) { throw new Exception($"Ошибка при вычислении подписи для вложения. {ex.Message}."); } header.SignaturePKCS7 = signature; changed = true; } } } if (changed) { string prefixForSerialize = FindPrefix(doc.DocumentElement, false); try { log.LogDebug($"Пытаемся обновить список вложений."); XmlElement attachmentHeaderListNew = this.SerializeToXmlElement(headerList, NamespaceUri.Smev3TypesBasic, prefixForSerialize); attachmentHeaderListNew = doc.ImportNode(attachmentHeaderListNew, true) as XmlElement; attachmentHeaderList.ParentNode.ReplaceChild(attachmentHeaderListNew, attachmentHeaderList); log.LogDebug("Список вложений успешно обновлен."); } catch (Exception ex) { throw new Exception($"Ошибка при попытке обновить подписанные вложения. {ex.Message}."); } } } } return(doc); }