public void ShouldDeriveKey(ProviderType providerType) { // TODO: VipNet does not support this feature - https://infotecs.ru/forum/topic/10142-oshibka-pri-sozdanii-klyucha-shifrovaniya-na-osnove-dannyih-polzovatelya-cryptderivekey/ if (providerType.IsVipNet()) { Assert.Ignore("VipNet does not support this feature"); } // Given var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType); // When Gost_28147_89_SymmetricAlgorithmBase randomKey1; Gost_28147_89_SymmetricAlgorithmBase randomKey2; Gost_28147_89_SymmetricAlgorithmBase randomKey3; using (var prf = new Gost_R3411_2012_512_PRF(initKey, Label, Seed)) { randomKey1 = prf.DeriveKey(); randomKey2 = prf.DeriveKey(); randomKey3 = prf.DeriveKey(); } // Then Assert.IsNotNull(randomKey1); Assert.IsNotNull(randomKey2); Assert.IsNotNull(randomKey3); AssertKeyIsValid(randomKey1); AssertKeyIsValid(randomKey2); AssertKeyIsValid(randomKey3); AssertKeysAreNotEqual(randomKey1, randomKey2); AssertKeysAreNotEqual(randomKey1, randomKey3); AssertKeysAreNotEqual(randomKey2, randomKey3); }
private Gost_R3411_PRF(ProviderType providerType, Gost_28147_89_SymmetricAlgorithm key, byte[] label, byte[] seed) : base(providerType) { if (label == null) { throw ExceptionUtility.ArgumentNull(nameof(label)); } if (seed == null) { throw ExceptionUtility.ArgumentNull(nameof(seed)); } _key = key; _hmac = CreateHMAC(key); var labelAndSeed = new byte[label.Length + seed.Length]; label.CopyTo(labelAndSeed, 0); seed.CopyTo(labelAndSeed, label.Length); _labelAndSeed = labelAndSeed; _buffer = new byte[labelAndSeed.Length + (_hmac.HashSize / 8)]; _value = labelAndSeed; _keyIndex = 0; }
public new EncryptedData Encrypt(XmlElement element, X509Certificate2 certificate) { if (element == null || certificate == null || !certificate.IsGost()) { return(base.Encrypt(element, certificate)); } var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm(); var encryptionKey = new Gost_28147_89_SymmetricAlgorithm(publicKey.ProviderType); var encryptedKey = new EncryptedKey(); encryptedKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate)); encryptedKey.EncryptionMethod = new EncryptionMethod(publicKey.KeyExchangeAlgorithm); encryptedKey.CipherData.CipherValue = EncryptKey(encryptionKey, publicKey); var encryptedData = new EncryptedData { Type = XmlEncElementUrl, EncryptionMethod = new EncryptionMethod(encryptionKey.AlgorithmName) }; encryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedKey)); encryptedData.CipherData.CipherValue = EncryptData(element, encryptionKey, false); return(encryptedData); }
public void ShouldDeriveBytes(ProviderType providerType) { // Given var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType); // When byte[] randomBytes1; byte[] randomBytes2; byte[] randomBytes3; using (var prf = new Gost_R3411_94_PRF(initKey, Label, Seed)) { randomBytes1 = prf.DeriveBytes(); randomBytes2 = prf.DeriveBytes(); randomBytes3 = prf.DeriveBytes(); } // Then Assert.IsNotNull(randomBytes1); Assert.IsNotNull(randomBytes2); Assert.IsNotNull(randomBytes3); Assert.AreEqual(256, 8 * randomBytes1.Length); Assert.AreEqual(256, 8 * randomBytes2.Length); Assert.AreEqual(256, 8 * randomBytes3.Length); CollectionAssert.AreNotEqual(randomBytes1, randomBytes2); CollectionAssert.AreNotEqual(randomBytes1, randomBytes3); CollectionAssert.AreNotEqual(randomBytes2, randomBytes3); }
private void InitDefaults(Gost_28147_89_SymmetricAlgorithm keyAlgorithm) { HashName = typeof(THash).Name; _keyAlgorithm = keyAlgorithm; _hmacHandle = CreateHashHMAC(keyAlgorithm.ProviderType, CryptoApiHelper.GetProviderHandle(keyAlgorithm.ProviderType), keyAlgorithm.GetSafeHandle()); }
public void ShouldDeriveKey(ProviderType providerType) { // Given var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType); // When Gost_28147_89_SymmetricAlgorithmBase randomKey1; Gost_28147_89_SymmetricAlgorithmBase randomKey2; Gost_28147_89_SymmetricAlgorithmBase randomKey3; using (var prf = new Gost_R3411_94_PRF(initKey, Label, Seed)) { randomKey1 = prf.DeriveKey(); randomKey2 = prf.DeriveKey(); randomKey3 = prf.DeriveKey(); } // Then Assert.IsNotNull(randomKey1); Assert.IsNotNull(randomKey2); Assert.IsNotNull(randomKey3); AssertKeyIsValid(randomKey1); AssertKeyIsValid(randomKey2); AssertKeyIsValid(randomKey3); AssertKeysAreNotEqual(randomKey1, randomKey2); AssertKeysAreNotEqual(randomKey1, randomKey3); AssertKeysAreNotEqual(randomKey2, randomKey3); }
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, Gost_28147_89_SymmetricAlgorithm sharedKey) { // Создание объекта для шифрации XML var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType); // Поиск элементов для шифрации var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']"); if (elements != null) { foreach (XmlElement element in elements) { // Шифрация элемента var encryptedData = encryptedXml.EncryptData(element, sharedKey, false); // Формирование элемента EncryptedData var elementEncryptedData = new EncryptedData(); elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl; elementEncryptedData.EncryptionMethod = new EncryptionMethod(sharedKey.AlgorithmName); elementEncryptedData.CipherData.CipherValue = encryptedData; // Замена элемента его зашифрованным представлением GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false); } } return(xmlDocument); }
private static Stream SendEncryptedDataStream(GostAsymmetricAlgorithm publicKey, Stream dataStream, out byte[] iv, out byte[] sessionKey) { var encryptedDataStream = new MemoryStream(); // Отправитель создает случайный сессионный ключ для шифрации данных using (var senderSessionKey = new Gost_28147_89_SymmetricAlgorithm(publicKey.ProviderType)) { // Отправитель передает получателю вектор инициализации iv = senderSessionKey.IV; // Отправитель шифрует сессионный ключ и передает его получателю var formatter = publicKey.CreateKeyExchangeFormatter(); sessionKey = formatter.CreateKeyExchangeData(senderSessionKey); // Отправитель шифрует данные с использованием сессионного ключа using (var encryptor = senderSessionKey.CreateEncryptor()) { var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write); dataStream.CopyTo(cryptoStream); cryptoStream.FlushFinalBlock(); } } encryptedDataStream.Position = 0; return(encryptedDataStream); }
public Gost_28147_89_SymmetricAlgorithmBase DeriveKey() { var randomPassword = GenerateNextBytes(); using (var hmac = CreateHMAC(_key)) { return(Gost_28147_89_SymmetricAlgorithm.CreateFromPassword(hmac, randomPassword)); } }
protected Gost_R3411_HMAC(Gost_28147_89_SymmetricAlgorithmBase keyAlgorithm, int hashSize) : base(keyAlgorithm.ProviderType, hashSize) { if (keyAlgorithm == null) { throw ExceptionUtility.ArgumentNull(nameof(keyAlgorithm)); } InitDefaults(Gost_28147_89_SymmetricAlgorithm.CreateFromKey(keyAlgorithm)); }
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, IEnumerable <X509Certificate2> certificates) { // Создание объекта для шифрации XML var encryptedXml = new GostEncryptedXml(); // Поиск элементов для шифрации var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']"); if (elements != null) { var elementIndex = 0; foreach (XmlElement element in elements) { // Формирование элемента EncryptedData var elementEncryptedData = new EncryptedData(); elementEncryptedData.Id = "EncryptedElement" + elementIndex++; elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl; elementEncryptedData.KeyInfo = new KeyInfo(); using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm()) { elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName); // Шифрация элемента с использованием симметричного ключа var encryptedElement = encryptedXml.EncryptData(element, sessionKey, false); foreach (var certificate in certificates) { // Шифрация сессионного ключа с использованием открытого ключа сертификата var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm()); // Формирование информации о зашифрованном сессионном ключе var encryptedSessionKey = new EncryptedKey(); encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData); encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostCryptoProKeyExportUrl); encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id }); encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate)); // Добавление ссылки на зашифрованный ключ, используемый при шифровании данных elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey)); } // Установка зашифрованных данных у объекта EncryptedData elementEncryptedData.CipherData.CipherValue = encryptedElement; } // Замена элемента его зашифрованным представлением GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false); } } return(xmlDocument); }
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, GostAsymmetricAlgorithm publicKey) { // Создание объекта для шифрации XML var encryptedXml = new GostEncryptedXml(publicKey.ProviderType); // Поиск элементов для шифрации var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']"); if (elements != null) { var elementIndex = 0; foreach (XmlElement element in elements) { // Создание случайного сессионного ключа using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm(publicKey.ProviderType)) { // Шифрация элемента 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(sessionKey.AlgorithmName); elementEncryptedData.CipherData.CipherValue = encryptedData; elementEncryptedData.KeyInfo = new KeyInfo(); // Формирование информации о зашифрованном сессионном ключе var encryptedSessionKey = new EncryptedKey(); encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData); encryptedSessionKey.EncryptionMethod = new EncryptionMethod(publicKey.KeyExchangeAlgorithm); 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); }
private byte[] EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod) { switch (keyExchangeExportMethod) { case GostKeyExchangeExportMethod.GostKeyExport: return(EncodeKeyExchangeInternal(keyExchangeAlgorithm, Constants.CALG_SIMPLE_EXPORT)); case GostKeyExchangeExportMethod.CryptoProKeyExport: return(EncodeKeyExchangeInternal(keyExchangeAlgorithm, Constants.CALG_PRO_EXPORT)); } throw ExceptionUtility.ArgumentOutOfRange(nameof(keyExchangeExportMethod)); }
public void ShouldEncryptAndDecrypt(ProviderType providerType) { // Given var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType); var dataStream = CreateDataStream(); // When var encryptedDataStream = EncryptDataStream(sharedKey, dataStream); var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream); // Then Assert.That(dataStream, Is.EqualTo(decryptedDataStream)); }
public void ShouldComputeHMAC(ProviderType providerType) { // Given var dataStream = CreateDataStream(); var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType); // When var hmacDataStream = CreateHmacDataStream(sharedKey, dataStream); var isValidHmacDataStream = VerifyHmacDataStream(sharedKey, hmacDataStream); // Then Assert.IsTrue(isValidHmacDataStream); }
/// <inheritdoc /> public override byte[] CreateKeyExchange(byte[] keyExchangeData) { if (keyExchangeData == null) { throw ExceptionUtility.ArgumentNull(nameof(keyExchangeData)); } using (var keyExchangeAlgorithm = new Gost_28147_89_SymmetricAlgorithm(_publicKey.ProviderType)) { keyExchangeAlgorithm.Key = keyExchangeData; return(CreateKeyExchangeData(keyExchangeAlgorithm)); } }
public void ShouldEncryptXml(ProviderType providerType) { // Given var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType); var xmlDocument = CreateXmlDocument(); var expectedXml = xmlDocument.OuterXml; // When var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, sharedKey); var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, sharedKey); var actualXml = decryptedXmlDocument.OuterXml; // Then Assert.AreEqual(expectedXml, actualXml); }
public override byte[] EncodeKeyExchange(SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod) { if (keyExchangeAlgorithm is Gost_28147_89_SymmetricAlgorithm symAlg) { return(EncodeKeyExchangeInternal(symAlg, keyExchangeExportMethod)); } if (keyExchangeAlgorithm is Gost_28147_89_SymmetricAlgorithmBase symAlgBase) { using (var gostKeyExchangeAlgorithm = new Gost_28147_89_SymmetricAlgorithm(symAlgBase.ProviderType)) { return(gostKeyExchangeAlgorithm.EncodePrivateKey(symAlgBase, keyExchangeExportMethod)); } } throw ExceptionUtility.Argument(nameof(keyExchangeAlgorithm), Resources.RequiredGost28147); }
private byte[] EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, int keyExchangeExportAlgId) { Gost_28147_89_KeyExchangeInfo keyExchangeInfo; SafeKeyHandleImpl keyExchangeHandle = null; try { var importedKeyBytes = CryptoApiHelper.EncodePublicBlob(_keyExchangeParameters, _keySize, _signatureAlgId); CryptoApiHelper.ImportCspBlob(importedKeyBytes, _provHandle, _keyHandle, out keyExchangeHandle); CryptoApiHelper.SetKeyExchangeExportAlgId(ProviderType, keyExchangeHandle, keyExchangeExportAlgId); var symKeyHandle = keyExchangeAlgorithm.GetSafeHandle(); keyExchangeInfo = CryptoApiHelper.ExportKeyExchange(symKeyHandle, keyExchangeHandle); } finally { keyExchangeHandle.TryDispose(); } return(keyExchangeInfo.Encode()); }
protected abstract THMAC CreateHMAC(Gost_28147_89_SymmetricAlgorithm key);
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, Gost_28147_89_SymmetricAlgorithm sharedKey) { // Создание объекта для дешифрации XML var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType, encryptedXmlDocument); var nsManager = new XmlNamespaceManager(encryptedXmlDocument.NameTable); nsManager.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl); // Поиск всех зашифрованных XML-элементов var encryptedDataList = encryptedXmlDocument.SelectNodes("//enc:EncryptedData", nsManager); if (encryptedDataList != null) { foreach (XmlElement encryptedData in encryptedDataList) { // Загрузка элемента EncryptedData var elementEncryptedData = new EncryptedData(); elementEncryptedData.LoadXml(encryptedData); // Расшифровка элемента EncryptedData var decryptedData = encryptedXml.DecryptData(elementEncryptedData, sharedKey); // Замена элемента EncryptedData его расшифрованным представлением encryptedXml.ReplaceData(encryptedData, decryptedData); } } return(encryptedXmlDocument); }
protected Gost_R3411_PRF(Gost_28147_89_SymmetricAlgorithmBase key, byte[] label, byte[] seed) : this(key.ProviderType, Gost_28147_89_SymmetricAlgorithm.CreateFromKey(key), label, seed) { }
protected override Gost_R3411_2012_256_HMAC CreateHMAC(Gost_28147_89_SymmetricAlgorithm key) { return(new Gost_R3411_2012_256_HMAC(key)); }
protected Gost_R3411_PRF(ProviderType providerType, byte[] key, byte[] label, byte[] seed) : this(providerType, Gost_28147_89_SymmetricAlgorithm.CreateFromSessionKey(providerType, key), label, seed) { }