/// <summary> /// Wrap ключа Gost28147CryptoServiceProvider на agree /// по <see cref="GostKeyWrapMethod.GostKeyWrap"/>. /// </summary> /// /// <param name="prov">Шифруемый ключ.</param> /// /// <returns>Зашифрованный симметричный ключ.</returns> /// /// <exception cref="CryptographicException">При ошибках /// на managed уровне.</exception> private byte[] GostWrap(Gost28147CryptoServiceProvider prov) { SafeKeyHandle hSimmKey = prov.SafeKeyHandle; GostWrappedKeyObject wrappedKey = new GostWrappedKeyObject(); SafeKeyHandle hExpKey = SafeKeyHandle.InvalidHandle; try { CapiHelper.ImportAndMakeSharedSecret(_safeProvHandle, CspProviderFlags.NoFlags, _publicObject, _safeKeyHandle, ref hExpKey, _algType); CapiHelper.SetKeyParamDw(hExpKey, GostConstants.KP_ALGID, GostConstants.CALG_SIMPLE_EXPORT); CapiHelper.ExportSessionWrapedKey(hSimmKey, hExpKey, wrappedKey); } finally { if (!hExpKey.IsClosed) { hExpKey.Close(); } } return(wrappedKey.GetXmlWrappedKey()); }
/// <summary> /// Wrap ключа Gost28147CryptoServiceProvider на agree /// по <see cref="GostKeyWrapMethod.CryptoProKeyWrap"/>. /// </summary> /// /// <param name="prov">Шифруемый ключ.</param> /// <param name="calgProExport">CALG алгоритма экспорта крипто про</param> /// <returns>Зашифрованный симметричный ключ.</returns> /// /// <exception cref="CryptographicException">При ошибках /// на managed уровне.</exception> private byte[] CryptoProWrap(Gost28147CryptoServiceProvider prov, int calgProExport = GostConstants.CALG_PRO_EXPORT) { if (calgProExport != GostConstants.CALG_PRO_EXPORT && calgProExport != GostConstants.CALG_PRO12_EXPORT) { throw new ArgumentOutOfRangeException("calgProExport"); } SafeKeyHandle hSimmKey = prov.SafeKeyHandle; GostWrappedKeyObject wrappedKey = new GostWrappedKeyObject(); SafeKeyHandle hExpKey = SafeKeyHandle.InvalidHandle; try { CapiHelper.ImportAndMakeSharedSecret(_safeProvHandle, CspProviderFlags.NoFlags, _publicObject, _safeKeyHandle, ref hExpKey, _algType); CapiHelper.SetKeyParamDw(hExpKey, GostConstants.KP_ALGID, calgProExport); CapiHelper.ExportSessionWrapedKey(hSimmKey, hExpKey, wrappedKey); } finally { if (!hExpKey.IsClosed) { hExpKey.Close(); } } return(wrappedKey.GetXmlWrappedKey()); }
/// <summary> /// Импортирует (дешифрует) секретный ключ. /// </summary> /// <param name="wrapped">Зашифрованный секретный ключ.</param> /// <param name="method">Алгоритм экспорта ключа.</param> public override SymmetricAlgorithm Unwrap(byte[] wrapped, GostKeyWrapMethod method) { GostWrappedKeyObject gwk = new GostWrappedKeyObject(); gwk.SetByXmlWrappedKey(wrapped); int calg = GostConstants.CALG_SIMPLE_EXPORT; if (method == GostKeyWrapMethod.CryptoProKeyWrap) { calg = GostConstants.CALG_PRO_EXPORT; } else if (method == GostKeyWrapMethod.CryptoPro12KeyWrap) { calg = GostConstants.CALG_PRO12_EXPORT; } else if (method != GostKeyWrapMethod.GostKeyWrap) { throw new ArgumentOutOfRangeException("method"); } SymmetricAlgorithm ret = null; // Сохраняем состояние algid GOST12147 using (SafeKeyHandle hExpKey = CapiHelper.DuplicateKey(SafeKeyHandle.DangerousGetHandle())) { CapiHelper.SetKeyParamDw(hExpKey, GostConstants.KP_ALGID, calg); SafeKeyHandle simmKey = SafeKeyHandle.InvalidHandle; CapiHelper.AcquireCsp(_parameters, out SafeProvHandle hProv); CapiHelper.ImportSessionWrappedKey( hProv, CspProviderFlags.NoFlags, gwk, hExpKey, ref simmKey); ret = new Gost28147CryptoServiceProvider(simmKey, hProv); } return(ret); }
/// <summary> /// Формирование данных обмена, на основе симметричного /// ключа шифрования сообщения ГОСТ 28147. /// </summary> /// /// <param name="data">"Чистый" симметричный ключ /// ГОСТ 28147.</param> /// /// <returns>Зашифрованные данные для отправки стороне /// получателю.</returns> /// /// <remarks> /// <if notdefined="symimp"><para>В данной сборке функция всегда /// возбуждает исключение <see cref="CryptographicException"/>. /// </para></if> /// <para>В зависимости от сборки функция может всегда возбуждать /// исключение <see cref="CryptographicException"/>, так /// как использует "чистый" ключ. По возможности используйте /// безопасную функцию /// <see cref="CreateKeyExchange(SymmetricAlgorithm, GostKeyWrapMethod)"/></para> /// </remarks> public override byte[] CreateKeyExchange(byte[] data) { using (Gost28147CryptoServiceProvider alg = new Gost28147CryptoServiceProvider()) { alg.Key = data; return(CreateKeyExchangeData(alg)); } }
/// <summary> /// Wrap ключа Gost28147CryptoServiceProvider на agree. /// </summary> /// /// <param name="prov">Шифруемый ключ</param> /// <param name="method">Метод зашифрования ключа.</param> /// /// <returns>Зашифрованный симметричный ключ</returns> private byte[] Wrap(Gost28147CryptoServiceProvider prov, GostKeyWrapMethod method) { if (method == GostKeyWrapMethod.CryptoProKeyWrap) { return(CryptoProWrap(prov)); } else if (method == GostKeyWrapMethod.CryptoPro12KeyWrap) { return(CryptoProWrap(prov, GostConstants.CALG_PRO12_EXPORT)); } else if (method == GostKeyWrapMethod.GostKeyWrap) { return(GostWrap(prov)); } else { throw new ArgumentOutOfRangeException("method"); } }
/// <summary> /// Зашифрование (экспорт) симметричного ключа. /// </summary> /// /// <remarks><para>Формат зашифрованного ключа зависит от метода /// зашифрования; для <see cref="GostKeyWrapMethod.GostKeyWrap"/> и /// <see cref="GostKeyWrapMethod.CryptoProKeyWrap"/> /// формат зашифрованного ключа определяется функцией /// <see cref="GostWrappedKey.GetXmlWrappedKey"/>.</para> /// /// <para>При зашифровании ключа используется синхропосылка /// заданная <see cref="SymmetricAlgorithm.IV"/></para> /// </remarks> /// /// <param name="alg">Объект класса <see cref="SymmetricAlgorithm"/>, /// содержащий симметричный ключ.</param> /// <param name="method">Алгоритм экспорта ключа.</param> /// /// <returns>Зашифрованный симметричный ключ.</returns> /// /// <seealso cref="GostWrappedKey"/> /// <seealso cref="GostSharedSecretCryptoServiceProvider.Unwrap"/> public override byte[] Wrap(SymmetricAlgorithm alg, GostKeyWrapMethod method) { Gost28147 gost = alg as Gost28147; if (gost == null) { throw new ArgumentException(nameof(alg)); } Gost28147CryptoServiceProvider prov = gost as Gost28147CryptoServiceProvider; if (prov == null) { using (Gost28147CryptoServiceProvider p = new Gost28147CryptoServiceProvider()) { return(p.Wrap(prov, method)); } } return(Wrap(prov, method)); }