Пример #1
0
        public void CreateKeyRoundtripBlob()
        {
            const int KeySize = 1024;

            byte[] blob;

            using (var gost = GetGostProvider())
            {
                CspKeyContainerInfo containerInfo = gost.CspKeyContainerInfo;
                Assert.Equal(Gost2012_512ProvType, containerInfo.ProviderType);
                Assert.Equal(KeySize, gost.KeySize);

                blob = gost.ExportCspBlob(false);
            }

            using (var gost = new Gost3410_2012_512CryptoServiceProvider())
            {
                gost.ImportCspBlob(blob);

                CspKeyContainerInfo containerInfo = gost.CspKeyContainerInfo;

                // The provider information is not persisted in the blob
                Assert.Equal(Gost2012_512ProvType, containerInfo.ProviderType);
                Assert.Equal(KeySize, gost.KeySize);
            }
        }
Пример #2
0
        // Шифрование тестового файла.
        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);
                        }
                    }
                }
            }
        }
Пример #3
0
        // Расшифрование тестового файла.
        static void DecryptTestFile(Gost3410_2012_512CryptoServiceProvider privateKey, string fileId = "2012_512")
        {
            // Открываем зашифрованный файл.
            using (FileStream ifs = new FileStream(string.Format(EncryptedFileName, fileId), FileMode.Open, FileAccess.Read))
            {
                // Читаем зашифрованный симметричный ключ.
                BinaryReader br = new BinaryReader(ifs);
                byte[]       cek;
                int          cekLength = br.ReadInt32();
                cek = br.ReadBytes(cekLength);

                // Читаем синхропосылку
                byte[] iv;
                int    ivLength = br.ReadInt32();
                iv = br.ReadBytes(ivLength);

                // Читаем открытый ключ.
                BinaryFormatter    formatter = new BinaryFormatter();
                Gost3410Parameters srcPublicKeyParameters =
                    (Gost3410Parameters)formatter.Deserialize(ifs);

                // Создаем agree ключ
                GostSharedSecretAlgorithm agree = privateKey.CreateAgree(
                    srcPublicKeyParameters);

                // Расшифровываем симметричный ключ на agree
                SymmetricAlgorithm symmetric = agree.Unwrap(cek,
                                                            GostKeyWrapMethod.CryptoPro12KeyWrap);
                symmetric.IV = iv;

                // Создаем поток разшифрования.
                ICryptoTransform transform = symmetric.CreateDecryptor();

                // Создаем поток разшифрования из файла.
                using (CryptoStream cs = new CryptoStream(ifs, transform, CryptoStreamMode.Read))
                {
                    // Открываем расшифрованный файл
                    using (FileStream ofs = new FileStream(string.Format(DecryptedFileName, fileId), FileMode.Create))
                    {
                        byte[] data = new byte[4096];
                        // и переписываем содержимое в выходной поток.
                        int length = cs.Read(data, 0, data.Length);
                        while (length > 0)
                        {
                            ofs.Write(data, 0, length);
                            length = cs.Read(data, 0, data.Length);
                        }
                    }
                }
            }
        }
Пример #4
0
        public void Constructor()
        {
            var gost = new Gost3410_2012_512CryptoServiceProvider();

            Assert.NotNull(gost);
        }
Пример #5
0
        public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal)
        {
            if (oid.Value == Oids.EcPublicKey && certificatePal != null)
            {
                return(DecodeECDsaPublicKey((CertificatePal)certificatePal));
            }

            int algId = Interop.Crypt32.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid.Value, OidGroup.PublicKeyAlgorithm, fallBackToAllGroups: true).AlgId;

            switch (algId)
            {
            case AlgId.CALG_RSA_KEYX:
            case AlgId.CALG_RSA_SIGN:
            {
                byte[] keyBlob = DecodeKeyBlob(CryptDecodeObjectStructType.CNG_RSA_PUBLIC_KEY_BLOB, encodedKeyValue);
                CngKey cngKey  = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob);
                return(new RSACng(cngKey));
            }

            //begin: gost
            case AlgId.CALG_GOST3410:
            {
                var cspObject = new GostKeyExchangeParameters();
                cspObject.DecodeParameters(encodedParameters);
                cspObject.DecodePublicKey(encodedKeyValue, algId);
                var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId);

                Gost3410CryptoServiceProvider gost_sp = new Gost3410CryptoServiceProvider();
                gost_sp.ImportCspBlob(cspBlobData);
                return(gost_sp);
            }

            case AlgId.CALG_GOST3410_2012_256:
            {
                var cspObject = new GostKeyExchangeParameters();
                cspObject.DecodeParameters(encodedParameters);
                cspObject.DecodePublicKey(encodedKeyValue, algId);
                var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId);

                Gost3410_2012_256CryptoServiceProvider gost_sp = new Gost3410_2012_256CryptoServiceProvider();
                gost_sp.ImportCspBlob(cspBlobData);
                return(gost_sp);
            }

            case AlgId.CALG_GOST3410_2012_512:
            {
                var cspObject = new GostKeyExchangeParameters();
                cspObject.DecodeParameters(encodedParameters);
                cspObject.DecodePublicKey(encodedKeyValue, algId);
                var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId);

                Gost3410_2012_512CryptoServiceProvider gost_sp = new Gost3410_2012_512CryptoServiceProvider();
                gost_sp.ImportCspBlob(cspBlobData);
                return(gost_sp);
            }

            //end: gost
            case AlgId.CALG_DSS_SIGN:
            {
                byte[] keyBlob = ConstructDSSPublicKeyCspBlob(encodedKeyValue, encodedParameters);
                DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
                dsa.ImportCspBlob(keyBlob);
                return(dsa);
            }

            default:
                throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
            }
        }
Пример #6
0
        /// <summary>
        /// Вспомогательный прокси метод для тестирования шифрования на асимметричном ключе
        /// </summary>
        /// <param name="gostKey"></param>
        private void Encrypt(AsymmetricAlgorithm gostKey)
        {
            if (gostKey is Gost3410 gost3410)
            {
                Console.WriteLine("Секретный ключ получен.");
                // и получаем открытый ключ.
                Gost3410Parameters publicKey = gost3410.ExportParameters(false);

                Console.WriteLine("На стороне отправителя...");
                // Полученный открытый ключ передаем отправителю сообщения.
                using (Gost3410CryptoServiceProvider pubKey = new Gost3410CryptoServiceProvider())
                {
                    pubKey.ImportParameters(publicKey);
                    Console.WriteLine("Открытый ключ получен.");

                    // Создаем Xml файл для зашифрования.
                    CreateSomeXml("ato_encrypt_2001.xml");
                    Console.WriteLine("Создан новый XML файл.");

                    // Зашифровываем узел, заданный xpath выражением, XML документа
                    // ato_encrypt.xml в документ a_encrypted.xml
                    // Для зашифрования используется открытый ключ pubKey.
                    Encrypt("ato_encrypt_2001.xml", "a_encrypted_2001.xml",
                            "//SomeNode[@ToEncrypt='true']",
                            "EncryptedElement1", pubKey, "KeyAlias");
                    Console.WriteLine("Узел XML файла зашифрован.");

                    Console.WriteLine("На стороне получателя...");

                    Decrypt("a_encrypted_2001.xml", "a_decrypted_2001.xml", gost3410, "KeyAlias");
                }
            }
            else if (gostKey is Gost3410_2012_256 gost3410_2012_256)
            {
                Console.WriteLine("Секретный ключ получен.");
                // и получаем открытый ключ.
                Gost3410Parameters publicKey = gost3410_2012_256.ExportParameters(false);

                Console.WriteLine("На стороне отправителя...");
                // Полученный открытый ключ передаем отправителю сообщения.
                using (Gost3410_2012_256CryptoServiceProvider pubKey = new Gost3410_2012_256CryptoServiceProvider())
                {
                    pubKey.ImportParameters(publicKey);
                    Console.WriteLine("Открытый ключ получен.");

                    // Создаем Xml файл для зашифрования.
                    CreateSomeXml("ato_encrypt_2012_256.xml");
                    Console.WriteLine("Создан новый XML файл.");

                    // Зашифровываем узел, заданный xpath выражением, XML документа
                    // ato_encrypt.xml в документ a_encrypted.xml
                    // Для зашифрования используется открытый ключ pubKey.
                    Encrypt("ato_encrypt_2012_256.xml", "a_encrypted_2012_256.xml",
                            "//SomeNode[@ToEncrypt='true']",
                            "EncryptedElement1", pubKey, "KeyAlias");
                    Console.WriteLine("Узел XML файла зашифрован.");

                    Console.WriteLine("На стороне получателя...");

                    Decrypt("a_encrypted_2012_256.xml", "a_decrypted_2012_256.xml", gost3410_2012_256, "KeyAlias");
                }
            }
            else if (gostKey is Gost3410_2012_512 gost3410_2012_512)
            {
                Console.WriteLine("Секретный ключ получен.");
                // и получаем открытый ключ.
                Gost3410Parameters publicKey = gost3410_2012_512.ExportParameters(false);

                Console.WriteLine("На стороне отправителя...");
                // Полученный открытый ключ передаем отправителю сообщения.
                using (Gost3410_2012_512CryptoServiceProvider pubKey = new Gost3410_2012_512CryptoServiceProvider())
                {
                    pubKey.ImportParameters(publicKey);
                    Console.WriteLine("Открытый ключ получен.");

                    // Создаем Xml файл для зашифрования.
                    CreateSomeXml("ato_encrypt_2012_512.xml");
                    Console.WriteLine("Создан новый XML файл.");

                    // Зашифровываем узел, заданный xpath выражением, XML документа
                    // ato_encrypt.xml в документ a_encrypted.xml
                    // Для зашифрования используется открытый ключ pubKey.
                    Encrypt("ato_encrypt_2012_512.xml", "a_encrypted_2012_512.xml",
                            "//SomeNode[@ToEncrypt='true']",
                            "EncryptedElement1", pubKey, "KeyAlias");
                    Console.WriteLine("Узел XML файла зашифрован.");

                    Console.WriteLine("На стороне получателя...");

                    Decrypt("a_encrypted_2012_512.xml", "a_decrypted_2012_512bui.xml", gost3410_2012_512, "KeyAlias");
                }
            }
            else
            {
                throw new NotSupportedException();
            }

            Console.WriteLine("XML документ расшифрован.");
        }
Пример #7
0
        // begin: gost
        public unsafe void SetCspPrivateKey(AsymmetricAlgorithm key)
        {
            if (key == null)
            {
                return;
            }
            CspKeyContainerInfo keyContainerInfo;

            switch (key.SignatureAlgorithm)
            {
            case GostConstants.XmlSignatureAlgorithm2001:
            {
                Gost3410CryptoServiceProvider asymmetricAlgorithm = key as Gost3410CryptoServiceProvider;
                keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo;
                break;
            }

            case GostConstants.XmlSignatureAlgorithm2012_256:
            {
                Gost3410_2012_256CryptoServiceProvider asymmetricAlgorithm = key as Gost3410_2012_256CryptoServiceProvider;
                keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo;
                break;
            }

            case GostConstants.XmlSignatureAlgorithm2012_512:
            {
                Gost3410_2012_512CryptoServiceProvider asymmetricAlgorithm = key as Gost3410_2012_512CryptoServiceProvider;
                keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo;
                break;
            }

            case "RSA":
            {
                RSACryptoServiceProvider asymmetricAlgorithm = key as RSACryptoServiceProvider;
                keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo;
                break;
            }

            case "DSA":
            {
                DSACryptoServiceProvider asymmetricAlgorithm = key as DSACryptoServiceProvider;
                keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo;
                break;
            }

            default:
            {
                throw new PlatformNotSupportedException();
            }
            }

            SafeLocalAllocHandle ptr = SafeLocalAllocHandle.InvalidHandle;

            fixed(char *keyContainerName = keyContainerInfo.KeyContainerName)
            fixed(char *providerName = keyContainerInfo.ProviderName)
            {
                CRYPT_KEY_PROV_INFO keyProvInfo = new CRYPT_KEY_PROV_INFO();

                keyProvInfo.pwszContainerName = keyContainerName;
                keyProvInfo.pwszProvName      = providerName;
                keyProvInfo.dwProvType        = keyContainerInfo.ProviderType;
                keyProvInfo.dwFlags           = keyContainerInfo.MachineKeyStore
                    ? CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET
                    : CryptAcquireContextFlags.None;
                keyProvInfo.cProvParam  = 0;
                keyProvInfo.rgProvParam = IntPtr.Zero;
                keyProvInfo.dwKeySpec   = (int)keyContainerInfo.KeyNumber;

                if (!Interop.crypt32.CertSetCertificateContextProperty(
                        _certContext,
                        CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID,
                        CertSetPropertyFlags.None,
                        &keyProvInfo))
                {
                    throw Marshal.GetLastWin32Error().ToCryptographicException();
                }
            }
        }