public void Encrypt2012_512() { using (Gost3410_2012_512 gost = GetGost2012_512Provider()) { Encrypt(gost); } }
public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, Gost3410_2012_512 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_2012_512 publicKey = GetGost3410_2012_512PublicKey(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)); }
// Шифрование тестового файла. static void EncryptTestFile( Gost3410_2012_512 publicKey, Gost3410_2012_512CryptoServiceProvider privateKey, string fileId = "2012_512") { // Создаем симметричный ключ. 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); } } } } }
/// <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(); }
public static X509SignatureGenerator CreateForGost(Gost3410_2012_512 key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return(new Gost3410_2012_512SignatureGenerator(key)); }
/// <summary> /// Устанавливает секретный ключ. /// </summary> /// /// <param name="key">Объект класса AsymmetricAlgorithm, /// содержащий секретный ключ.</param> /// /// <remarks><para>Ключ должен быть установлен до вызова /// функций восстановления ключа.</para> /// </remarks> /// /// <argnull name="key" /> /// <exception cref="CryptographicException"> /// <paramref name="key"/> не поддерживает алгоритм /// <see cref="Gost3410_2012_512"/>.</exception> public override void SetKey(AsymmetricAlgorithm key) { if (key == null) { throw new ArgumentNullException("key"); } Gost3410_2012_512 gost = key as Gost3410_2012_512; if (gost == null) { throw new CryptographicException( Resources.Cryptography_Assymmetric_GOST3410_2012_512); } gostKey_ = gost; }
public void TestKeyExchange2012_512() { // Ассиметричный ключ получателя. Gost3410_2012_512 AssymKey; // Синхропосылка. byte[] IV; // Создаем случайный открытый ключ. using (Gost3410_2012_512 gkey = GetGostProvider2012_512()) { 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_2012_512 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_2012_512 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; }
/// <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(); } }
public ICertificatePal CopyWithPrivateKey(Gost3410_2012_512 gost) { return(CopyWithPersistedCapiKey(((Gost3410_2012_512CryptoServiceProvider)gost).CspKeyContainerInfo)); }
internal Gost3410_2012_512SignatureGenerator(Gost3410_2012_512 key) { Debug.Assert(key != null); _key = key; }
/// <summary> /// Инициализирует новый экземпляр класса <c>GostKeyValue</c> с заданным /// открытым ключом ГОСТ 34.10-2012 512. /// </summary> /// /// <param name="key">Экземпляр реализации класса /// <see cref="Gost3410_2012_512"/>, в котором содержится открытый /// ключ.</param> public Gost2012_512KeyValue(Gost3410_2012_512 key) { _key = key; }
/// <summary> /// Инициализирует новый экземпляр класса <c>GostKeyValue</c> с новым, /// сгенерированным случайным образом открытым ключом ГОСТ 34.10-2012 512. /// </summary> /// <remarks>При создании нового ключа ГОСТ 34.10-2012 512 этот конструктор /// использует реализацию <see cref="Gost3410_2012_512"/> по /// умолчанию, как определено классом /// <see cref="System.Security.Cryptography.CryptoConfig"/>.</remarks> public Gost2012_512KeyValue() { _key = (Gost3410_2012_512)Gost3410_2012_512.Create(); }