This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others. We welcome contributions.
Сейчас для совместимости с некоторыми сторонними реализациями (ФСС) необходимо осуществлять импорт ключа 12 госта с использование старого CryptoProKeyWrap. Так как определить тип KeyWrap по ключу внутри Xml невозможно, то делаем так
private SymmetricAlgorithm CryptoProUnwrap(byte[] wrapped)
{
try
{
return this.CryptoProUnwrap(wrapped, GostConstants.CALG_PRO12_EXPORT);
}
catch (CryptographicException ex)
{
if (Marshal.GetHRForException(ex) == -2146893819)
{
// bad data - пробуем импорт на старом алгоритме
return this.CryptoProUnwrap(wrapped, GostConstants.CALG_PRO_EXPORT);
}
else
{
throw;
}
}
}
Проблема возникает при использовании метода ImportKeyBlob
internal static int ImportKeyBlob(byte[] keyBlob,
SafeProvHandle hProv, CspProviderFlags flags,
SafeKeyHandle hImportKey, out SafeKeyHandle hKey)
{
int keyFlags = MapCspKeyFlags((int)flags);
bool ret = CapiHelper.CryptImportKey(hProv, keyBlob,
keyBlob.Length, hImportKey, keyFlags, out hKey);
if (!ret)
throw new CryptographicException(Marshal.GetLastWin32Error());
int algid_class = BitConverter.ToInt32(keyBlob, 4) & (7 << 13);
if (algid_class == (5 << 13))
return (int)KeyNumber.Exchange;
return (int)KeyNumber.Signature;
}
Так как для Unix Marshal.GetLastWin32Error() вернёт некорректный код ошибки. При исправлении на
internal static int ImportKeyBlob(byte[] keyBlob,
SafeProvHandle hProv, CspProviderFlags flags,
SafeKeyHandle hImportKey, out SafeKeyHandle hKey)
{
int keyFlags = MapCspKeyFlags((int)flags);
bool ret = CapiHelper.CryptImportKey(hProv, keyBlob,
keyBlob.Length, hImportKey, keyFlags, out hKey);
if (!ret)
{
var hr = Interop.CPError.GetHRForLastWin32Error();
throw hr.ToCryptographicException();
}
int algid_class = BitConverter.ToInt32(keyBlob, 4) & (7 << 13);
if (algid_class == (5 << 13))
return (int)KeyNumber.Exchange;
return (int)KeyNumber.Signature;
}
работает корректно.
Проблема технически может возникать и в других сценариях, ибо код CapiHelper полностью перенесён из Шарпея, и обработка ошибок полностью виндовая, на unix возможны и другие некорректные коды. С виду мы больше нигде по ним не ветвимся, поэтому править массово пока не будем (из за опасений, что получение кода ошибки в других методах теоретически может приходить к перетиранию кода, и тогда будем получать ошибку и на windows).
Хорошо добывать бы тест на это (возможно в рамках LibCore с переносом сюда).
Сейчас для совместимости с некоторыми сторонними реализациями (ФСС) необходимо осуществлять импорт ключа 12 госта с использование старого
CryptoProKeyWrap
. Так как определить тип KeyWrap по ключу внутри Xml невозможно, то делаем такПроблема возникает при использовании метода
ImportKeyBlob
Так как для Unix
Marshal.GetLastWin32Error()
вернёт некорректный код ошибки. При исправлении наработает корректно.
Проблема технически может возникать и в других сценариях, ибо код
CapiHelper
полностью перенесён из Шарпея, и обработка ошибок полностью виндовая, на unix возможны и другие некорректные коды. С виду мы больше нигде по ним не ветвимся, поэтому править массово пока не будем (из за опасений, что получение кода ошибки в других методах теоретически может приходить к перетиранию кода, и тогда будем получать ошибку и на windows).Хорошо добывать бы тест на это (возможно в рамках LibCore с переносом сюда).