Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,340 Сказал «Спасибо»: 550 раз Поблагодарили: 2212 раз в 1727 постах
|
Цитата:// stream information (not used) Вот здесь как раз и нужно прописать вызов записи в файл блока зашифрованных данных |
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 20.08.2015(UTC) Сообщений: 90 Откуда: Москва Сказал(а) «Спасибо»: 6 раз
|
Автор: Андрей * Цитата:// stream information (not used) Вот здесь как раз и нужно прописать вызов записи в файл блока зашифрованных данных у меня есть код EncryptDecryptStream1.zip (275kb) загружен 31 раз(а).код шифрует, но почему-то не добавляет сертификаты а КриптоПРО говорит, что он не может найти ни одного открытого ключа но ни у кого "нет времени" подсказать
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 12.02.2022(UTC) Сообщений: 1 Откуда: Жуковский
|
Это конечно "тихий ужас". Нужные функции, но о них так мало информации. Собирали по крупицам из прошлых сообщений, из обращений в ТП. Оставляю тут рабочий вариант потокового шифрования на несколько сертификатов. И как пример предлагаю добавить в SDK.
Код:
/// <summary>
/// Кодирование CMS/PKCS#7 больших файлов
/// </summary>
/// <param name="certsCollection">Коллекция сертификатов</param>
/// <param name="inFile">Входящий поток (файл для шифрования)</param>
/// <param name="outFile">Исходящий поток (файл с результатом шифрования)</param>
/// <returns></returns>
public bool Encrypt(X509Certificate2Collection certsCollection, FileStream inFile, FileStream outFile)
{
bool res = false;
CMSG_ENVELOPED_ENCODE_INFO EnvelopedEncodeInfo;
CMSG_STREAM_INFO StreamInfo;
CERT_CONTEXT[] CertContexts;
CERT_INFO[] CertInfoStructuresArray;
IntPtr CertInfoPtr = IntPtr.Zero;
IntPtr EnvelopedEncodeInfoPtr = IntPtr.Zero;
IntPtr hMsg = IntPtr.Zero;
IntPtr pbPtr = IntPtr.Zero;
GCHandle gchandle = new GCHandle();
byte[] pbData;
long dwFileSize;
long dwRemaining;
int dwSize;
bool bResult = false;
var allocatedMemoryToCertInfo = new List<IntPtr>();
try
{
// Размер файла
dwFileSize = inFile.Length;
pbData = new byte[BlockSize];
m_callbackFile = outFile;
// Заполняем структуру StreamInfo
StreamInfo = new CMSG_STREAM_INFO(CMSG_INDEFINITE_LENGTH,
new PFN_CMSG_STREAM_OUTPUT(StreamOutputCallback),
IntPtr.Zero);
int certCount = certsCollection.Count;
CertContexts = new CERT_CONTEXT[certCount];
CertInfoStructuresArray = new CERT_INFO[certCount];
int certCounter = 0;
foreach (var cert in certsCollection)
{
CertContexts[certCounter] = (CERT_CONTEXT)Marshal.PtrToStructure(cert.Handle, typeof(CERT_CONTEXT));
CertInfoStructuresArray[certCounter] = (CERT_INFO)Marshal.PtrToStructure(CertContexts[certCounter].pCertInfo, typeof(CERT_INFO));
certCounter++;
}
int intPtrSize = Marshal.SizeOf(typeof(IntPtr));
CertInfoPtr = Marshal.AllocHGlobal(intPtrSize * certCount);
for (int i = 0; i < certCount; i++)
{
IntPtr pCERT_INFO = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CERT_INFO)));
allocatedMemoryToCertInfo.Add(pCERT_INFO);
Marshal.StructureToPtr(CertInfoStructuresArray[i], pCERT_INFO, false);
Marshal.WriteIntPtr(CertInfoPtr, i * intPtrSize, pCERT_INFO);
}
// Заполнить структуру CMSG_ENVELOPED_ENCODE_INFO
EnvelopedEncodeInfo = new CMSG_ENVELOPED_ENCODE_INFO(Marshal.SizeOf(typeof(CMSG_ENVELOPED_ENCODE_INFO)));
EnvelopedEncodeInfo.hCryptProv = IntPtr.Zero;
EnvelopedEncodeInfo.ContentEncryptionAlgorithm.pszObjId = szOID_CP_GOST_28147;
EnvelopedEncodeInfo.cRecipients = (uint)certCount;
EnvelopedEncodeInfo.rgpRecipients = CertInfoPtr;
// Распределяем память под структуру
EnvelopedEncodeInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(EnvelopedEncodeInfo));
Marshal.StructureToPtr(EnvelopedEncodeInfo, EnvelopedEncodeInfoPtr, false);
hMsg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CMSG_ENVELOPED,
ref EnvelopedEncodeInfo,
null,
ref StreamInfo);
if (hMsg.Equals(IntPtr.Zero))
{
throw new Exception("CryptMsgOpenToEncode error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}
gchandle = GCHandle.Alloc(pbData, GCHandleType.Pinned);
pbPtr = gchandle.AddrOfPinnedObject();
dwRemaining = dwFileSize;
if (dwFileSize < BlockSize)
{
dwSize = (int)dwFileSize;
}
else
{
dwSize = BlockSize;
}
while (dwRemaining > 0)
{
inFile.Read(pbData, 0, dwSize);
// Вызываем обработку блока
bResult = CryptMsgUpdate(hMsg, pbPtr, dwSize, dwRemaining <= dwSize);
if (!bResult)
{
throw new CryptographicException("CryptMsgUpdate error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}
// Переходим к следующему блоку
dwRemaining -= dwSize;
if (dwRemaining < dwSize)
{
dwSize = (int)dwRemaining;
}
}
res = true;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
finally
{
// Освобождение памяти
if (gchandle.IsAllocated)
{
gchandle.Free();
}
if (!CertInfoPtr.Equals(IntPtr.Zero))
{
Marshal.FreeHGlobal(CertInfoPtr);
}
foreach (IntPtr ptr in allocatedMemoryToCertInfo)
{
if (!ptr.Equals(IntPtr.Zero))
{
Marshal.FreeHGlobal(ptr);
}
}
if (m_callbackFile != null)
{
m_callbackFile.Close();
}
if (!hMsg.Equals(IntPtr.Zero))
{
CryptMsgClose(hMsg);
}
}
return res;
}
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close