public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, Gost3410 privateKey) { if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } if (privateKey == null) { throw new ArgumentNullException(nameof(privateKey)); } if (certificate.HasPrivateKey) { throw new InvalidOperationException(SR.Cryptography_Cert_AlreadyHasPrivateKey); } using (Gost3410 publicKey = GetGost3410PublicKey(certificate)) { if (publicKey == null) { throw new ArgumentException(SR.Cryptography_PrivateKey_WrongAlgorithm); } //Gost3410Parameters currentParameters = publicKey.ExportParameters(false); //Gost3410Parameters newParameters = privateKey.ExportParameters(false); } ICertificatePal pal = certificate.Pal.CopyWithPrivateKey(privateKey); return(new X509Certificate2(pal)); }
public void Encrypt2001() { using (Gost3410 gost = GetGostProvider()) { Encrypt(gost); } }
// Шифрование тестового файла. static void EncryptTestFile( Gost3410 publicKey, Gost3410CryptoServiceProvider privateKey, string fileId = "2001") { // Создаем симметричный ключ. Gost28147 symmetric = Gost28147.Create(); // Открываем ключ отправителя. Gost3410Parameters srcPublicKeyParameters = privateKey.ExportParameters(false); // Создаем agree ключ GostSharedSecretAlgorithm agree = privateKey.CreateAgree( publicKey.ExportParameters(false)); // Зашифровываем симметричный ключ на agree ключе. byte[] WrappedKey = agree.Wrap(symmetric, GostKeyWrapMethod.CryptoPro12KeyWrap); // Создаем поток шифратора. ICryptoTransform transform = symmetric.CreateEncryptor(); // Создаем зашифрованный файл. using (FileStream ofs = new FileStream(string.Format(EncryptedFileName, fileId), FileMode.Create)) { BinaryWriter bw = new BinaryWriter(ofs); // Записываем зашифрованный симметричный ключ. bw.Write(WrappedKey.Length); bw.Write(WrappedKey); // Записываем синхропосылку bw.Write(symmetric.IV.Length); bw.Write(symmetric.IV); // Передаем открытый ключ. BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ofs, srcPublicKeyParameters); // Создаем поток шифрования для записи в файл. using (CryptoStream cs = new CryptoStream(ofs, transform, CryptoStreamMode.Write)) { byte[] data = new byte[4096]; // Открываем входной файл. using (FileStream ifs = new FileStream(string.Format(SourceFileName, fileId), FileMode.Open, FileAccess.Read)) { // и переписываем содержимое в выходной поток. int length = ifs.Read(data, 0, data.Length); while (length > 0) { cs.Write(data, 0, length); length = ifs.Read(data, 0, data.Length); } } } } }
// begin: gost public static X509SignatureGenerator CreateForGost(Gost3410 key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return(new Gost3410SignatureGenerator(key)); }
/// <summary> /// Create a self-signed certificate using the established subject, key, and optional /// extensions. /// </summary> /// <param name="notBefore"> /// The oldest date and time where this certificate is considered valid. /// Typically <see cref="DateTimeOffset.UtcNow"/>, plus or minus a few seconds. /// </param> /// <param name="notAfter"> /// The date and time where this certificate is no longer considered valid. /// </param> /// <returns> /// An <see cref="X509Certificate2"/> with the specified values. The returned object will /// assert <see cref="X509Certificate2.HasPrivateKey" />. /// </returns> /// <exception cref="ArgumentException"> /// <paramref name="notAfter"/> represents a date and time before <paramref name="notAfter"/>. /// </exception> /// <exception cref="InvalidOperationException"> /// A constructor was used which did not accept a signing key. /// </exception>> /// <exception cref="CryptographicException"> /// Other errors during the certificate creation process. /// </exception> public X509Certificate2 CreateSelfSigned(DateTimeOffset notBefore, DateTimeOffset notAfter) { if (notAfter < notBefore) { throw new ArgumentException(SR.Cryptography_CertReq_DatesReversed); } if (_key == null) { throw new InvalidOperationException(SR.Cryptography_CertReq_NoKeyProvided); } Debug.Assert(_generator != null); byte[] serialNumber = new byte[8]; RandomNumberGenerator.Fill(serialNumber); using (X509Certificate2 certificate = Create( SubjectName, _generator, notBefore, notAfter, serialNumber)) { RSA rsa = _key as RSA; if (rsa != null) { return(certificate.CopyWithPrivateKey(rsa)); } ECDsa ecdsa = _key as ECDsa; if (ecdsa != null) { return(certificate.CopyWithPrivateKey(ecdsa)); } Gost3410 gost3410 = _key as Gost3410; if (gost3410 != null) { return(certificate.CopyWithPrivateKey(gost3410)); } Gost3410_2012_256 gost3410_2012_256 = _key as Gost3410_2012_256; if (gost3410_2012_256 != null) { return(certificate.CopyWithPrivateKey(gost3410_2012_256)); } Gost3410_2012_512 gost3410_2012_512 = _key as Gost3410_2012_512; if (gost3410_2012_512 != null) { return(certificate.CopyWithPrivateKey(gost3410_2012_512)); } } Debug.Fail($"Key was of no known type: {_key?.GetType().FullName ?? "null"}"); throw new CryptographicException(); }
private static bool VerifySignature(Gost3410 publicKey, Stream dataStream, byte[] signature) { byte[] hash; using (var hashAlg = new Gost3411HashAlgorithm()) { hash = hashAlg.ComputeHash(dataStream); } return(publicKey.VerifySignature(hash, signature)); }
private static byte[] CreateSignature(Gost3410 privateKey, Stream dataStream) { byte[] hash; using (var hashAlg = new Gost3411HashAlgorithm()) { hash = hashAlg.ComputeHash(dataStream); } return(privateKey.CreateSignature(hash)); }
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, Gost3410 publicKey) { // Создание объекта для шифрации XML var encryptedXml = new GostEncryptedXml(); // Поиск элементов для шифрации var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']"); if (elements != null) { var elementIndex = 0; foreach (XmlElement element in elements) { // Создание случайного сессионного ключа using (var sessionKey = new Gost28147SymmetricAlgorithm()) { // Шифрация элемента var encryptedData = encryptedXml.EncryptData(element, sessionKey, false); // Шифрация сессионного ключа с использованием публичного асимметричного ключа var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKey); // Формирование элемента EncryptedData var elementEncryptedData = new EncryptedData(); elementEncryptedData.Id = "EncryptedElement" + elementIndex++; elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl; elementEncryptedData.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGost28147Url); elementEncryptedData.CipherData.CipherValue = encryptedData; elementEncryptedData.KeyInfo = new KeyInfo(); // Формирование информации о зашифрованном сессионном ключе var encryptedSessionKey = new EncryptedKey(); encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData); encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostKeyTransportUrl); encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id }); encryptedSessionKey.KeyInfo.AddClause(new KeyInfoName { Value = "KeyName1" }); // Добавление ссылки на зашифрованный ключ, используемый при шифровании данных elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey)); // Замена элемента его зашифрованным представлением GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false); } } } return(xmlDocument); }
/// <summary> /// Зашифровать симметричный ключ /// </summary> /// <param name="symmKey"></param> /// <param name="recipientName"></param> /// <returns></returns> public byte[] EncryptSymmKey(Gost28147 symmKey, string recipientName) { Log.DssLogger.Debug($"Шифрование симметричного ключа на получателя {recipientName}"); byte[] returnArray; try { X509Certificate2 cert = _certificateService.FindAddressBookCertificateBySubjectName(recipientName) .Result; // Если ничего не нашли - выходим if (cert == null) { return(null); } // Открытый ключ получателя. AsymmetricAlgorithm pk = cert.PublicKey.Key; Gost3410 recipient = pk as Gost3410; if (recipient == null) { throw new CryptographicException("Not a gost certificate"); } GostKeyExchangeFormatter keyFormatter = new GostKeyExchangeFormatter(recipient); byte[] transport = keyFormatter.CreateKeyExchangeData(symmKey); // Создаем зашифрованный файл. using (MemoryStream ms = new MemoryStream()) { // Записываем зашифрованный симметричный ключ в виде транспортного представления. BinaryWriter bw = new BinaryWriter(ms); bw.Write(transport.Length); bw.Write(transport); // Записываем синхропосылку bw.Write(symmKey.IV.Length); bw.Write(symmKey.IV); returnArray = ms.ToArray(); } } catch (Exception exp) { Log.DssLogger.Error($"Ошибка при зашифровании симметричного ключа: {exp}"); returnArray = null; } return(returnArray); }
private static byte[] CreateSignature(Gost3410 privateKey, Stream dataStream) { byte[] hash; using (var hashAlg = new Gost3411HashAlgorithm()) { hash = hashAlg.ComputeHash(dataStream); } var formatter = new GostSignatureFormatter(privateKey); return(formatter.CreateSignature(hash)); }
public static byte[] EncryptKey(Gost28147 sessionKey, Gost3410 publicKey) { if (sessionKey == null) { throw ExceptionUtility.ArgumentNull("sessionKey"); } if (publicKey == null) { throw ExceptionUtility.ArgumentNull("publicKey"); } var formatter = new GostKeyExchangeFormatter(publicKey); return(formatter.CreateKeyExchangeData(sessionKey)); }
private void Form1_Load(object sender, EventArgs e) { mode = new byte[3]; mode[0] = 0x01; mode[1] = 0x02; mode[2] = 0x03; cert = get_certificate_by_name("flex2424"); CspParameters csp_params = new CspParameters(75, null, container_name); csp = new Gost3410CryptoServiceProvider(csp_params); sign = cert.PublicKey.Key as Gost3410; foreach (StoreLocation storeLocation in (StoreLocation[]) Enum.GetValues(typeof(StoreLocation))) { if (storeLocation.ToString() == "CurrentUser") { foreach (StoreName storeName in (StoreName[]) Enum.GetValues(typeof(StoreName))) { if (storeName.ToString() == "My") { // Выводим все сертификаты в /Текущий пользователь/Личное X509Store store = new X509Store(storeName, storeLocation); try { store.Open(OpenFlags.OpenExistingOnly); foreach (X509Certificate2 certificate in store.Certificates) { comboBox1.Items.Add(certificate.GetName()); } } catch (CryptographicException) { MessageBox.Show("Exception in comboBox"); } } } } } }
/// <summary> /// Получает ключ для расшифровки на основе зашифрованных данных (из примеров криптопро) /// </summary> /// <param name="exml"></param> /// <param name="encryptedData"></param> /// <returns>Алгоритм для расшифровки</returns> private SymmetricAlgorithm GetDecryptionKey(EncryptedXml exml, EncryptedData encryptedData) { IEnumerator encryptedKeyEnumerator = encryptedData.KeyInfo.GetEnumerator(); // Проходим по всем KeyInfo while (encryptedKeyEnumerator.MoveNext()) { // Пропускам все что неизвестно. KeyInfoEncryptedKey current = encryptedKeyEnumerator.Current as KeyInfoEncryptedKey; if (current == null) { continue; } // До первого EncryptedKey EncryptedKey encryptedKey = current.EncryptedKey; if (encryptedKey == null) { continue; } KeyInfo keyinfo = encryptedKey.KeyInfo; // Проходим по всем KeyInfo зашифрования ключа. IEnumerator srcKeyEnumerator = keyinfo.GetEnumerator(); while (srcKeyEnumerator.MoveNext()) { // Пропускам все что неизвестно. KeyInfoX509Data keyInfoCert = srcKeyEnumerator.Current as KeyInfoX509Data; if (keyInfoCert == null) { continue; } AsymmetricAlgorithm alg = certOur.PrivateKey; // Приватный ключ, открытый ключ которого мы отправляли при шифровании запроса Gost3410 myKey = alg as Gost3410; // Преобразования if (myKey == null) { continue; } // Получаем и возвращаем ключ для расшифровки return(CPEncryptedXml.DecryptKeyClass(encryptedKey.CipherData.CipherValue, myKey, encryptedData.EncryptionMethod.KeyAlgorithm)); } } return(null); }
public void TestKeyExchange2001() { // Ассиметричный ключ получателя. Gost3410 AssymKey; // Синхропосылка. byte[] IV; // Создаем случайный открытый ключ. using (Gost3410 gkey = GetGostProvider2001()) { AssymKey = gkey; // Создаем случайный секретный ключ, который необходимо передать. Gost28147 key = new Gost28147CryptoServiceProvider(); // Синхропосылка не входит в GostKeyTransport и должна // передаваться отдельно. IV = key.IV; // Создаем форматтер, шифрующий на ассиметричном ключе получателя. GostKeyExchangeFormatter Formatter = new GostKeyExchangeFormatter(AssymKey); // GostKeyTransport - формат зашифрованной для безопасной передачи // ключевой информации. GostKeyTransport encKey = Formatter.CreateKeyExchange(key); // Шифруемая строка string message = "012345678901234567890"; byte[] sourceBytes = Encoding.ASCII.GetBytes(message); Console.WriteLine("** Строка до шифрования: " + message); // Шифруем строку на сессионном ключе byte[] encBytes = GostEncrypt(key, sourceBytes); Console.WriteLine("** Строка после шифрования: " + Encoding.ASCII.GetString(encBytes)); // Получатель расшифровывает GostKeyTransport и само сообщение. byte[] decBytes = GostDecrypt(encKey, encBytes, IV, AssymKey); Console.WriteLine("** Строка после расшифрования: " + Encoding.ASCII.GetString(decBytes)); Assert.Equal(sourceBytes, decBytes); } }
/// <summary> /// Create a CertificateRequest for the specified subject name, GOST3410 key, and hash algorithm. /// </summary> /// <param name="subjectName"> /// The parsed representation of the subject name for the certificate or certificate request. /// </param> /// <param name="key"> /// n GOST3410 key whose public key material will be included in the certificate or certificate request. /// This key will be used as a private key if <see cref="CreateSelfSigned" /> is called. /// </param> /// <param name="hashAlgorithm"> /// The hash algorithm to use when signing the certificate or certificate request. /// </param> public CertificateRequest(X500DistinguishedName subjectName, Gost3410 key, HashAlgorithmName hashAlgorithm) { if (subjectName == null) { throw new ArgumentNullException(nameof(subjectName)); } if (key == null) { throw new ArgumentNullException(nameof(key)); } if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm)); } SubjectName = subjectName; _key = key; _generator = X509SignatureGenerator.CreateForGost(key); PublicKey = _generator.PublicKey; HashAlgorithm = hashAlgorithm; }
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, Gost3410 signingKey) { // Создание подписчика XML-документа var signedXml = new SignedXml(xmlDocument); // Установка ключа для создания подписи signedXml.SigningKey = signingKey; signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigGost3410Url; // Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования //var dataReference = new Reference { Uri = "#Id1", DigestMethod = GostSignedXml.XmlDsigGost3411Url }; var dataReference = new Reference(); dataReference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); dataReference.AddTransform(new XmlDsigExcC14NTransform()); dataReference.DigestMethod = SignedXml.XmlDsigGost3411Url; dataReference.Uri = ""; // Установка ссылки на узел signedXml.AddReference(dataReference); // Установка информации о ключе, который использовался для создания подписи var keyInfo = new KeyInfo(); keyInfo.AddClause(new GostKeyValue(signingKey)); signedXml.KeyInfo = keyInfo; // Вычисление подписи signedXml.ComputeSignature(); // Получение XML-представления подписи var signatureXml = signedXml.GetXml(); // Добавление подписи в исходный документ xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true)); return(xmlDocument); }
/// <summary> /// Инициализирует новый экземпляр класса <c>GostKeyValue</c> с новым, /// сгенерированным случайным образом открытым ключом ГОСТ 34.10-2001. /// </summary> /// <remarks>При создании нового ключа ГОСТ 34.10-2001 этот конструктор /// использует реализацию <see cref="Gost3410"/> по /// умолчанию, как определено классом /// <see cref="System.Security.Cryptography.CryptoConfig"/>.</remarks> public GostKeyValue() { _key = (Gost3410)Gost3410.Create(); }
/// <summary> /// Create a certificate using the established subject, key, and optional extensions using /// the provided certificate as the issuer. /// </summary> /// <param name="issuerCertificate"> /// An X509Certificate2 instance representing the issuing Certificate Authority (CA). /// </param> /// <param name="notBefore"> /// The oldest date and time where this certificate is considered valid. /// Typically <see cref="DateTimeOffset.UtcNow"/>, plus or minus a few seconds. /// </param> /// <param name="notAfter"> /// The date and time where this certificate is no longer considered valid. /// </param> /// <param name="serialNumber"> /// The serial number to use for the new certificate. This value should be unique per issuer. /// The value is interpreted as an unsigned (big) integer in big endian byte ordering. /// </param> /// <returns> /// An <see cref="X509Certificate2"/> with the specified values. The returned object will /// not assert <see cref="X509Certificate2.HasPrivateKey" />. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="issuerCertificate"/> is null.</exception> /// <exception cref="ArgumentException"> /// The <see cref="X509Certificate2.HasPrivateKey"/> value for <paramref name="issuerCertificate"/> is false. /// </exception> /// <exception cref="ArgumentException"> /// The type of signing key represented by <paramref name="issuerCertificate"/> could not be determined. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="notAfter"/> represents a date and time before <paramref name="notBefore"/>. /// </exception> /// <exception cref="ArgumentException"><paramref name="serialNumber"/> is null or has length 0.</exception> /// <exception cref="ArgumentException"> /// <paramref name="issuerCertificate"/> has a different key algorithm than the requested certificate. /// </exception> /// <exception cref="InvalidOperationException"> /// <paramref name="issuerCertificate"/> is an RSA certificate and this object was created via a constructor /// which does not accept a <see cref="RSASignaturePadding"/> value. /// </exception> public X509Certificate2 Create( X509Certificate2 issuerCertificate, DateTimeOffset notBefore, DateTimeOffset notAfter, byte[] serialNumber) { if (issuerCertificate == null) { throw new ArgumentNullException(nameof(issuerCertificate)); } if (!issuerCertificate.HasPrivateKey) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerRequiresPrivateKey, nameof(issuerCertificate)); } if (notAfter < notBefore) { throw new ArgumentException(SR.Cryptography_CertReq_DatesReversed); } if (serialNumber == null || serialNumber.Length < 1) { throw new ArgumentException(SR.Arg_EmptyOrNullArray, nameof(serialNumber)); } if (issuerCertificate.PublicKey.Oid.Value != PublicKey.Oid.Value) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_AlgorithmMustMatch, issuerCertificate.PublicKey.Oid.Value, PublicKey.Oid.Value), nameof(issuerCertificate)); } DateTime notBeforeLocal = notBefore.LocalDateTime; if (notBeforeLocal < issuerCertificate.NotBefore) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_NotBeforeNotNested, notBeforeLocal, issuerCertificate.NotBefore), nameof(notBefore)); } DateTime notAfterLocal = notAfter.LocalDateTime; // Round down to the second, since that's the cert accuracy. // This makes one method which uses the same DateTimeOffset for chained notAfters // not need to do the rounding locally. long notAfterLocalTicks = notAfterLocal.Ticks; long fractionalSeconds = notAfterLocalTicks % TimeSpan.TicksPerSecond; notAfterLocalTicks -= fractionalSeconds; notAfterLocal = new DateTime(notAfterLocalTicks, notAfterLocal.Kind); if (notAfterLocal > issuerCertificate.NotAfter) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_NotAfterNotNested, notAfterLocal, issuerCertificate.NotAfter), nameof(notAfter)); } // Check the Basic Constraints and Key Usage extensions to help identify inappropriate certificates. // Note that this is not a security check. The system library backing X509Chain will use these same criteria // to determine if a chain is valid; and a user can easily call the X509SignatureGenerator overload to // bypass this validation. We're simply helping them at signing time understand that they've // chosen the wrong cert. var basicConstraints = (X509BasicConstraintsExtension)issuerCertificate.Extensions[Oids.BasicConstraints2]; var keyUsage = (X509KeyUsageExtension)issuerCertificate.Extensions[Oids.KeyUsage]; if (basicConstraints == null) { throw new ArgumentException(SR.Cryptography_CertReq_BasicConstraintsRequired, nameof(issuerCertificate)); } if (!basicConstraints.CertificateAuthority) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerBasicConstraintsInvalid, nameof(issuerCertificate)); } if (keyUsage != null && (keyUsage.KeyUsages & X509KeyUsageFlags.KeyCertSign) == 0) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerKeyUsageInvalid, nameof(issuerCertificate)); } AsymmetricAlgorithm key = null; string keyAlgorithm = issuerCertificate.GetKeyAlgorithm(); X509SignatureGenerator generator; try { switch (keyAlgorithm) { case Oids.Rsa: if (_rsaPadding == null) { throw new InvalidOperationException(SR.Cryptography_CertReq_RSAPaddingRequired); } RSA rsa = issuerCertificate.GetRSAPrivateKey(); key = rsa; generator = X509SignatureGenerator.CreateForRSA(rsa, _rsaPadding); break; case Oids.EcPublicKey: ECDsa ecdsa = issuerCertificate.GetECDsaPrivateKey(); key = ecdsa; generator = X509SignatureGenerator.CreateForECDsa(ecdsa); break; //begin: gost case Oids.Gost3410EL: Gost3410 gost3410 = issuerCertificate.GetGost3410PrivateKey(); key = gost3410; generator = X509SignatureGenerator.CreateForGost(gost3410); break; case Oids.Gost3410_2012_256: Gost3410_2012_256 gost3410_2012_256 = issuerCertificate.GetGost3410_2012_256PrivateKey(); key = gost3410_2012_256; generator = X509SignatureGenerator.CreateForGost(gost3410_2012_256); break; case Oids.Gost3410_2012_512: Gost3410_2012_512 gost3410_2012_512 = issuerCertificate.GetGost3410_2012_512PrivateKey(); key = gost3410_2012_512; generator = X509SignatureGenerator.CreateForGost(gost3410_2012_512); break; //end: gost default: throw new ArgumentException( SR.Format(SR.Cryptography_UnknownKeyAlgorithm, keyAlgorithm), nameof(issuerCertificate)); } return(Create(issuerCertificate.SubjectName, generator, notBefore, notAfter, serialNumber)); } finally { key?.Dispose(); } }
/// <summary> /// Инициализирует новый экземпляр класса <c>GostKeyValue</c> с заданным /// открытым ключом ГОСТ 34.10-2001. /// </summary> /// /// <param name="key">Экземпляр реализации класса /// <see cref="Gost3410"/>, в котором содержится открытый /// ключ.</param> public GostKeyValue(Gost3410 key) { _key = key; }
// begin: gost public ICertificatePal CopyWithPrivateKey(Gost3410 gost) { return(CopyWithPersistedCapiKey(((Gost3410CryptoServiceProvider)gost).CspKeyContainerInfo)); }
/// <summary> /// Формирование сигнатуры для серверной подписи /// </summary> /// <param name="alg"></param> /// <param name="data"></param> /// <param name="detached"></param> /// <returns></returns> public static byte[] ComputeSignature(Gost3410 alg, byte[] data, bool detached = true) { var certBytes = alg.ContainerCertificateRaw; var _x509CertificateParser = new BCX509.X509CertificateParser(); var bcCert = _x509CertificateParser.ReadCertificate(certBytes); ICollection <BCX509.X509Certificate> certPath = new List <BCX509.X509Certificate>(); certPath.Add(bcCert); IDigest digest; string hashOid; string signOid; if (GostCryptoConfig.ProviderType == ProviderTypes.CryptoPro256) { digest = new GOST3411_2012_256Digest(); signOid = Constants.OID_GR3410_12_256; hashOid = Constants.OID_GR3411_12_256; } else if (GostCryptoConfig.ProviderType == ProviderTypes.CryptoPro512) { digest = new GOST3411_2012_512Digest(); signOid = Constants.OID_GR3410_12_512; hashOid = Constants.OID_GR3411_12_512; } else { digest = new Gost3411Digest(); signOid = Constants.OID_GR3410_2001; hashOid = Constants.OID_GR3411_2001; } byte[] dataHash = ComputeDigest(digest, data); // Construct SignerInfo.signedAttrs Asn1EncodableVector signedAttributesVector = new Asn1EncodableVector(); // Add PKCS#9 contentType signed attribute signedAttributesVector.Add( new Org.BouncyCastle.Asn1.Cms.Attribute( new DerObjectIdentifier(Constants.szOID_RSA_contentType), new DerSet(new DerObjectIdentifier(Constants.szOID_RSA_data)))); // Add PKCS#9 messageDigest signed attribute signedAttributesVector.Add( new Org.BouncyCastle.Asn1.Cms.Attribute( new DerObjectIdentifier(Constants.szOID_RSA_messageDigest), new DerSet(new DerOctetString(dataHash)))); // Add PKCS#9 signingTime signed attribute signedAttributesVector.Add( new Org.BouncyCastle.Asn1.Cms.Attribute( new DerObjectIdentifier(Constants.szOID_RSA_signingTime), new DerSet(new Org.BouncyCastle.Asn1.Cms.Time(new DerUtcTime(DateTime.UtcNow))))); DerSet signedAttributes = new DerSet(signedAttributesVector); byte[] pkcs1Digest = ComputeDigest(digest, signedAttributes.GetDerEncoded()); //byte[] pkcs1DigestInfo = CreateDigestInfo(pkcs1Digest, hashOid); var formatter = new GostSignatureFormatter(alg); var signature = formatter.CreateSignature(pkcs1Digest); // Construct SignerInfo SignerInfo signerInfo = new SignerInfo( new SignerIdentifier(new IssuerAndSerialNumber(bcCert.IssuerDN, bcCert.SerialNumber)), new AlgorithmIdentifier(new DerObjectIdentifier(hashOid), null), signedAttributes, new AlgorithmIdentifier(new DerObjectIdentifier(signOid), null), new DerOctetString(signature), null); // Construct SignedData.digestAlgorithms Asn1EncodableVector digestAlgorithmsVector = new Asn1EncodableVector(); digestAlgorithmsVector.Add(new AlgorithmIdentifier(new DerObjectIdentifier(hashOid), null)); // Construct SignedData.encapContentInfo ContentInfo encapContentInfo = new ContentInfo( new DerObjectIdentifier(Constants.szOID_RSA_data), (detached) ? null : new DerOctetString(data)); // Construct SignedData.certificates Asn1EncodableVector certificatesVector = new Asn1EncodableVector(); foreach (BCX509.X509Certificate cert in certPath) { certificatesVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded()))); } // Construct SignedData.signerInfos Asn1EncodableVector signerInfosVector = new Asn1EncodableVector(); signerInfosVector.Add(signerInfo.ToAsn1Object()); // Construct SignedData SignedData signedData = new SignedData( new DerSet(digestAlgorithmsVector), encapContentInfo, new BerSet(certificatesVector), null, new DerSet(signerInfosVector)); // Construct top level ContentInfo ContentInfo contentInfo = new ContentInfo( new DerObjectIdentifier(Constants.szOID_RSA_signedData), signedData); return(contentInfo.GetDerEncoded()); }
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, Gost3410 privateKey) { // Создание объекта для дешифрации XML var encryptedXml = new GostEncryptedXml(encryptedXmlDocument); // Добавление ссылки на приватный асимметричный ключ encryptedXml.AddKeyNameMapping("KeyName1", privateKey); // Расшифровка зашифрованных элементов документа encryptedXml.DecryptDocument(); return(encryptedXmlDocument); }
internal Gost3410SignatureGenerator(Gost3410 key) { Debug.Assert(key != null); _key = key; }
/// <summary> /// Шифрует сессионный ключ с помощью указанного асимметричного ключа ГОСТ Р 34.10. /// </summary> /// <param name="sessionKey">Шифруемый сессионный ключ.</param> /// <param name="publicKey">Открытый ключ ГОСТ Р 34.10 для шифрования сессионного ключа.</param> /// <returns>Массив байт, содержащий зашифрованный сессионный ключ.</returns> /// <remarks>Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется.</remarks> public static byte[] EncryptKey(Gost28147 sessionKey, Gost3410 publicKey) { return(GostEncryptedXmlImpl.EncryptKey(sessionKey, publicKey)); }