Crypto PRO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ C # рдореЗрдВ рдЗрд▓реЗрдХреНрдЯреНрд░реЙрдирд┐рдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреА рдорд╛рдиреНрдпрддрд╛

рдЗрд▓реЗрдХреНрдЯреНрд░реЙрдирд┐рдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ (рдмрд╛рдж рдореЗрдВ рдЗрд▓реЗрдХреНрдЯреНрд░реЙрдирд┐рдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд) рдХреЗ рд╡рд┐рд╖рдп рдкрд░ рдмрд╛рддрдЪреАрдд рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реБрдП, рдЗрд╕реЗ рд╕рддреНрдпрд╛рдкрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ рдХрд╛рд░реНрдп рдХреЗ рдЕрдзрд┐рдХ рдХрдард┐рди рднрд╛рдЧ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рдпрд╛ - рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд╛ рдирд┐рд░реНрдорд╛рдгред рдпрд╣ рд▓реЗрдЦ рдереЛрдбрд╝рд╛ рд╕рд░рд▓ рд╣реИред рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛрдб рдХреНрд░рд┐рдкреНрдЯреЛ рдкреНрд░реЛ .NET рдПрд╕рдбреАрдХреЗ рд╕реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдПрдХ рдЕрдиреБрдХреВрд▓рди рд╣реИред рд╣рдо GOST R 34.10-2001 рдФрд░ GOST R 34.10-2012 рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕рднреА рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ CRYPTO PRO рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХрд╛рд░реНрдп 3 рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИ: рдПрдХ рдЕрд▓рдЧ рд╣рд╕реНрддрд╛рдХреНрд╖рд░, рдкреАрдбреАрдПрдл рдореЗрдВ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдФрд░ рдПрдордПрд╕ рд╡рд░реНрдб рдореЗрдВ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ред

рдкреГрдердХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд╛ рд╕рддреНрдпрд╛рдкрди:

//dataFileRawBytes -     ContentInfo contentInfo = new ContentInfo(dataFileRawBytes); SignedCms signedCms = new SignedCms(contentInfo, true); //signatureFileRawBytes -    signedCms.Decode(signatureFileRawBytes); if (signedCms.SignerInfos.Count == 0) { //     } foreach (SignerInfo signerInfo in signedCms.SignerInfos) { //   DateTime? signDate = (signerInfo.SignedAttributes .Cast<CryptographicAttributeObject>() .FirstOrDefault(x => x.Oid.Value == "1.2.840.113549.1.9.5") ?.Values[0] as Pkcs9SigningTime)?.SigningTime; bool valid; try { signerInfo.CheckSignature(true); valid = true; } catch (CryptographicException exc) { valid = false; } //   .     X509Certificate2 certificate = signerInfo.Certificate; 

рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рд╕рднреА рдХреЛрдб рдореЗрдВ рд╣реИрдВ, рдореИрдВ рдХреЗрд╡рд▓ рдкреНрд░рдорд╛рдг рдкрддреНрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдЖрдХрд░реНрд╖рд┐рдд рдХрд░реВрдВрдЧрд╛, рд╣рдореЗрдВ рдмрд╛рдж рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЕрд▓рдЧ рд╕реЗ рдкреНрд░рдорд╛рдг рдкрддреНрд░ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВрдЧреЗред

рдЦреИрд░, рдХреЛрд╢рд┐рд╢-рдХреИрдЪ рдФрд░ рджреВрд╕рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдм рдХреБрдЫ рд▓рдкреЗрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдордд рднреВрд▓рдирд╛ред рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдореИрдВ рдЬрд╛рдирдмреВрдЭрдХрд░ рд╡реЙрд▓реНрдпреВрдо рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВ

рдкреАрдбреАрдПрдл рдореЗрдВ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╕рддреНрдпрд╛рдкрдиред рдпрд╣рд╛рдВ рд╣рдореЗрдВ iTextSharp (5.5.13 рд▓рд┐рдЦрдиреЗ рдХреЗ рд╕рдордп рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг) рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

  using (MemoryStream fileStream = new MemoryStream(dataFileRawBytes)) using (PdfReader pdfReader = new PdfReader(fileStream)) { AcroFields acroFields = pdfReader.AcroFields; //    List<string> signatureNames = acroFields.GetSignatureNames(); if (!signatureNames.Any()) { //   } foreach (string signatureName in signatureNames) { //       PdfDictionary singleSignature = acroFields.GetSignatureDictionary(signatureName); PdfString asString1 = singleSignature.GetAsString(PdfName.CONTENTS); byte[] signatureBytes = asString1.GetOriginalBytes(); RandomAccessFileOrArray safeFile = pdfReader.SafeFile; PdfArray asArray = singleSignature.GetAsArray(PdfName.BYTERANGE); using ( Stream stream = new RASInputStream( new RandomAccessSourceFactory().CreateRanged( safeFile.CreateSourceView(), asArray.AsLongArray()))) { using (MemoryStream ms = new MemoryStream((int)stream.Length)) { stream.CopyTo(ms); byte[] data = ms.GetBuffer(); ContentInfo contentInfo = new ContentInfo(data); SignedCms signedCms = new SignedCms(contentInfo, true); signedCms.Decode(signatureBytes); bool checkResult; //    ,    try { signedCms.CheckSignature(true); checkResult = true; } catch (Exception) { checkResult = false; } foreach (SignerInfo signerInfo in signedCms.SignerInfos) { //   DateTime? signDate = (signerInfo.SignedAttributes .Cast<CryptographicAttributeObject>() .FirstOrDefault(x => x.Oid.Value == "1.2.840.113549.1.9.5") ?.Values[0] as Pkcs9SigningTime)?.SigningTime; //  X509Certificate2 certificate = signerInfo.Certificate; } } } } } 

рдлрд┐рд░, рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИред рдЬрдм рддрдХ рдореБрдЭреЗ рдУрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдХрд╣рдирд╛ рд╣реИ, "1.2.840.113549.1.9.5" рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд░рдиреЗ рдХреА рддрд╛рд░реАрдЦ рдХрд╛ рдУрдб рд╣реИред

рдФрд░ рд╣рдорд╛рд░реА рд╕реВрдЪреА рдореЗрдВ рдЕрдВрддрд┐рдо docx рд╣реИ, рд╢рд╛рдпрдж рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╡рд┐рдХрд▓реНрдк:

  using (MemoryStream fileStream = new MemoryStream(dataFileRawBytes)) using (Package filePackage = Package.Open(fileStream)) { PackageDigitalSignatureManager digitalSignatureManager = new PackageDigitalSignatureManager(filePackage); if (!digitalSignatureManager.IsSigned) { //    } foreach (PackageDigitalSignature signature in digitalSignatureManager.Signatures) { DateTime? signDate = signature.SigningTime; bool checkResult = signature.Verify() == VerifyResult.Success; //      X509Certificate2 certificate = new X509Certificate2(signature.Signer); } } 

рдЕрдм рд╣рдо рдкреНрд░рдорд╛рдг рдкрддреНрд░ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдкреНрд░рдорд╛рдгрдкрддреНрд░реЛрдВ рдХреА рдкреВрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рдорд╛рдиреНрдп рдХрд░реЗрдВрдЧреЗред рдЗрд╕рд▓рд┐рдП, рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЛ рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рддрд╣рдд рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕рдХреЗ рдкрд╛рд╕ рдиреЗрдЯрд╡рд░реНрдХ рддрдХ рдкрд╣реБрдВрдЪ рд╣реИред

рдФрд░ рдлрд┐рд░ рдирд░рдХ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдУрдЖрдИрдбреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рдорд╛рдг рдкрддреНрд░ рдХреЗ рдорд╛рд▓рд┐рдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХреА рдЬрд╛рдП, рдЗрд╕рд▓рд┐рдП рдореИрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░реВрдВрдЧрд╛ред рдЬреЛрд░ рд╕реЗ рд╣рдВрд╕рдирд╛: рд╕рд░реНрдХрд╕ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдЧрдВрднреАрд░рддрд╛ рд╕реЗ, рдЖрдк рдЙрди рд▓реЛрдЧреЛрдВ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд╛рдЧрдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдУрдЖрдИрдбреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдпрд╣ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИ:

  private static void FillElectronicSignature(X509Certificate2 certificate) { foreach (KeyValuePair<string, string> item in ParseCertificatesSubject(certificate.Subject)) { switch (item.Key) { case "C": string certificatesCountryName = item.Value; break; case "S": string certificatesState = item.Value; break; case "L": string certificatesLocality = item.Value; break; case "O": string certificatesOrganizationName = item.Value; break; case "OU": string certificatesOrganizationalUnitName = item.Value; break; case "CN": string certificatesCommonName = item.Value; break; case "E": string certificatesEmail = item.Value; break; case "STREET": string certificatesStreet = item.Value; break; //  ,  Window ,     ,   ,  INN //       deploy    // ,   -  case "": case "INN": case "1.2.643.3.131.1.1": string certificatesInn = item.Value; break; //  case "": case "OGRN": case "1.2.643.100.1": string certificatesOgrn = item.Value; break; //  case "": case "SNILS": case "1.2.643.100.3": string certificatesSnils = item.Value; break; case "SN": string certificatesOwnerLastName = item.Value; break; case "G": string certificatesOwnerFirstName = item.Value; break; //    default           } } DateTime certificateNotBefore = certificate.NotBefore; DateTime certificateNotAfter = certificate.NotAfter; string certificatesSerialNumber = certificate.SerialNumber; if (!certificate.Verify()) { //   using (X509Chain x509Chain = new X509Chain()) { x509Chain.Build(certificate); //    X509ChainStatus[] statuses = x509Chain.ChainStatus; //      int,    int certificatesErrorCode = statuses.Aggregate(X509ChainStatusFlags.NoError, (acc, chainStatus) => acc | chainStatus.Status, result => (int)result); } } } /// <summary> ///        /// </summary> private static Dictionary<string, string> ParseCertificatesSubject(string subject) { Dictionary<string, string> result = new Dictionary<string, string>(); //  ,     int quotationMarksCount = 0; //    "  " bool isKey = true; //    string key = string.Empty; //    string value = string.Empty; for (int i = 0; i < subject.Length; i++) { char c = subject[i]; if (isKey && c == '=') { isKey = false; continue; } if (isKey) key += c; else { if (c == '"') quotationMarksCount++; bool isItemEnd = (c == ',' && subject.Length >= i + 1 && subject[i + 1] == ' '); bool isLastChar = subject.Length == i + 1; if ((isItemEnd && quotationMarksCount % 2 == 0) || isLastChar) { if (isItemEnd) i++; if (isLastChar) value += c; isKey = true; if (value.StartsWith("\"") && value.EndsWith("\"")) value = value.Substring(1, value.Length - 2); value = value.Replace("\"\"", "\""); result.Add(key, value); key = string.Empty; value = string.Empty; quotationMarksCount = 0; continue; } value += c; } } return result; } 

рд╕рд╛рд░ рдХреА рдмреЗрд╣рддрд░ рд╕рдордЭ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдХрдо рд╣реИред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрд╣ рд╕рдм рд╣реИ, рдореИрдВ рдкреНрд░рдорд╛рдг рдкрддреНрд░ рд╕реЗ рдУрдЖрдИрдбреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдХрд┐рд╕реА рднреА рдХрд╛рд░рдг рдЖрд▓реЛрдЪрдирд╛ рдкрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

Source: https://habr.com/ru/post/hi426645/


All Articles