コード例 #1
0
 public void Encrypt2012_512()
 {
     using (Gost3410_2012_512 gost = GetGost2012_512Provider())
     {
         Encrypt(gost);
     }
 }
コード例 #2
0
        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));
        }
コード例 #3
0
ファイル: GostSharedSecretTest.cs プロジェクト: Trivin/corefx
        // Шифрование тестового файла.
        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);
                        }
                    }
                }
            }
        }
コード例 #4
0
        /// <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();
        }
コード例 #5
0
        public static X509SignatureGenerator CreateForGost(Gost3410_2012_512 key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            return(new Gost3410_2012_512SignatureGenerator(key));
        }
コード例 #6
0
        /// <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;
        }
コード例 #7
0
ファイル: GostKeyExchangeTests.cs プロジェクト: Trivin/corefx
        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);
            }
        }
コード例 #8
0
        /// <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;
        }
コード例 #9
0
        /// <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();
            }
        }
コード例 #10
0
 public ICertificatePal CopyWithPrivateKey(Gost3410_2012_512 gost)
 {
     return(CopyWithPersistedCapiKey(((Gost3410_2012_512CryptoServiceProvider)gost).CspKeyContainerInfo));
 }
コード例 #11
0
        internal Gost3410_2012_512SignatureGenerator(Gost3410_2012_512 key)
        {
            Debug.Assert(key != null);

            _key = key;
        }
コード例 #12
0
 /// <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;
 }
コード例 #13
0
 /// <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();
 }