Статус: Активный участник
Группы: Участники
Зарегистрирован: 06.07.2012(UTC) Сообщений: 267 Откуда: Калининград Сказал «Спасибо»: 51 раз Поблагодарили: 30 раз в 22 постах
|
Добрый день. Пытаюсь на c# через P/Invoke разобрать запрос на сертификат и в итоге получить открытый ключ. По описанию в данной теме (https://www.cryptopro.ru/CryptoPro/forum/view.asp?q=1085), нужно дважды вызвать CryptDecodeObject - сперва получить структуру CERT_SIGNED_CONTENT а потом из нее получить CERT_REQUEST_INFO. Структуру CERT_SIGNED_CONTENT вроде удалось получить, а вот когда проделываю decode для нее, то указатель pcbStructInfo2 остается 0. Может быть я неправильно подаю полученную структуру на вход к CryptDecodeObject? Подскажите, пожалуйста, знающие люди! Результат в консоли и код прилагаю: Код:public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
uint pcbStructInfo = 0;
byte[] raw = Convert.FromBase64String(File.ReadAllText("request.pem"));
CryptDecodeObject(65537,1,raw,raw.Length,0x8,IntPtr.Zero, ref pcbStructInfo);
Console.WriteLine("pcbStructInfo: " + pcbStructInfo);
IntPtr pvStructInfo = Marshal.AllocHGlobal((IntPtr)pcbStructInfo);
Console.WriteLine("pvStructInfo: " + pvStructInfo);
CryptDecodeObject(65537,1,raw,raw.Length,0x8,pvStructInfo, ref pcbStructInfo);
CERT_SIGNED_CONTENT_INFO str = new CERT_SIGNED_CONTENT_INFO();
str = Marshal.PtrToStructure<CERT_SIGNED_CONTENT_INFO>(pvStructInfo);
Console.WriteLine("str.SignatureAlgorithm.pszObjId: " + str.SignatureAlgorithm.pszObjId);
byte[] raw2 = getBytes(str);
uint pcbStructInfo2 = 0;
CryptDecodeObject(65537,4,raw2,raw2.Length,0x8,IntPtr.Zero, ref pcbStructInfo2);
Console.WriteLine("pcbStructInfo2: " + pcbStructInfo2);
/*
IntPtr pvStructInfo2 = Marshal.AllocHGlobal((IntPtr)pcbStructInfo2);
Console.WriteLine(pvStructInfo2);
CERT_REQUEST_INFO str2 = new CERT_REQUEST_INFO();
str = Marshal.PtrToStructure<CERT_SIGNED_CONTENT_INFO>(pvStructInfo2);
Console.WriteLine(str2.SubjectPublicKeyInfo.PublicKey.ToString());
*/
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
static byte[] getBytes(CERT_SIGNED_CONTENT_INFO str)
{
int size = Marshal.SizeOf(str);
byte[] arr = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, ptr, false);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
return arr;
}
[DllImport("crypt32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern Boolean CryptDecodeObject(
UInt32 dwCertEncodingType,
UInt32 lpszStructType,
byte[] pbEncoded,
Int32 cbEncoded,
UInt32 dwFlags,
IntPtr pvStructInfo,
ref UInt32 pcbStructInfo
);
public struct CERT_SIGNED_CONTENT_INFO {
public CRYPTOAPI_BLOB ToBeSigned;
public CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
public CRYPT_BIT_BLOB Signature;
}
public struct CRYPTOAPI_BLOB {
public UInt32 cbData;
public IntPtr pbData;
}
public struct CRYPT_ALGORITHM_IDENTIFIER {
[MarshalAs(UnmanagedType.LPStr)]
public String pszObjId;
public CRYPTOAPI_BLOB Parameters;
}
public struct CRYPT_BIT_BLOB {
public UInt32 cbData;
public IntPtr pbData;
public UInt32 cUnusedBits;
}
public struct CERT_REQUEST_INFO {
public uint dwVersion;
public CRYPTOAPI_BLOB Subject;
public CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
public uint cAttribute;
public CRYPT_ATTRIBUTE rgAttribute;
}
public struct CERT_PUBLIC_KEY_INFO {
public CRYPT_ALGORITHM_IDENTIFIER Algorithm;
public CRYPT_BIT_BLOB PublicKey;
}
public struct CRYPT_ATTRIBUTE {
public string pszObjId;
public UInt32 cValue;
public CRYPTOAPI_BLOB rgValue;
}
|