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); } }
// Шифрование тестового файла. 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); } } } } }
// Расшифрование тестового файла. 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); } } } } }
public void Constructor() { var gost = new Gost3410_2012_512CryptoServiceProvider(); Assert.NotNull(gost); }
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); } }
/// <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 документ расшифрован."); }
// 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(); } } }