Проверка dll на подлинность

300
05 мая 2018, 14:35

Подскажите как мне проверить загружаемую dll на подлинность? Подписал dll ключом строгого имени,но не нашел способа проверки данного подписывания

Answer 1

Чтобы проверить подлинность сборки, нужно сделать две вещи: проверить корректность цифровой подписи, и проверить соответствие ее открытого ключа (т.е., что подпись действительно ваша). Для проверки подписи можно использовать интерфейс IClrStrongName. Для проверки открытого ключа нужно просто побайтово сравнить AsssemblyName.PublicKeyToken с ожидаемым ключом.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
namespace WindowsFormsTest1
{
    public partial class Form1 : Form
    {        
        public Form1()
        {
            InitializeComponent();            
        }     
        private void button1_Click(object sender, EventArgs e)
        {
            string path="c:\\lib\\my.dll";
            byte[] myToken = new byte[]    { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0A, 0xFF };
            if( CheckSignature(path) && CheckPublicKey(path, myToken)) MessageBox.Show("Valid");
            else MessageBox.Show("Invalid");            
        }
        //проверка корректности цифровой подписи
        bool CheckSignature(string path)
        {              
            var clrStrongName = (IClrStrongName)RuntimeEnvironment.GetRuntimeInterfaceAsObject(
                new Guid("B79B0ACD-F5CD-409b-B5A5-A16244610B92"), new Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D")
            );
            bool verificationForced;
            try
            {
                int result = clrStrongName.StrongNameSignatureVerificationEx(path, true, out verificationForced);
                if (result == 0)
                {
                    return true;
                }
                else return false;
            }
            finally
            {
                Marshal.ReleaseComObject(clrStrongName);
            }
        }
        //проверка корректности цифровой подписи (для сборки, размещенной в памяти)
        bool CheckSignature(byte[] bytes)
        { 
            IntPtr p = Marshal.AllocHGlobal(bytes.Length);
            Marshal.Copy(bytes, 0, p, bytes.Length);                        
            var clrStrongName = (IClrStrongName)RuntimeEnvironment.GetRuntimeInterfaceAsObject(
                new Guid("B79B0ACD-F5CD-409b-B5A5-A16244610B92"), new Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D")
            );
            int outFlags;
            try
            {
                int result = clrStrongName.StrongNameSignatureVerificationFromImage(
                    p, bytes.Length, 0x00000001 /*SN_INFLAG_FORCE_VER*/, out outFlags
                    );
                if (result == 0)
                {
                    return true;
                }
                else return false;
            }
            finally
            {
                Marshal.ReleaseComObject(clrStrongName);
                Marshal.FreeHGlobal(p);
            }
        }           

        //проверка соответствия ключа
        bool CheckPublicKey(string path,byte[] expectedToken)
        {
            AssemblyName an = AssemblyName.GetAssemblyName(path);
            byte[] assToken = an.GetPublicKeyToken();
            if (assToken == null || assToken.Length == 0) return false;
            if (assToken.Length != expectedToken.Length)
            {
                return false; 
            }
            else
            {                
                for (int i = 0; i < assToken.Length; i++)
                    if (assToken[i] != expectedToken[i]) { return false; }                
            }
            return true;
        }    
    }
    [ComConversionLoss, Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [ComImport]
    internal interface IClrStrongName
    {
        [PreserveSig]
        int GetHashFromAssemblyFile([MarshalAs(UnmanagedType.LPStr)] [In] string pszFilePath, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash);
        [PreserveSig]
        int GetHashFromAssemblyFileW([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash);
        [PreserveSig]
        int GetHashFromBlob([In] IntPtr pbBlob, [MarshalAs(UnmanagedType.U4)] [In] int cchBlob, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash);
        [PreserveSig]
        int GetHashFromFile([MarshalAs(UnmanagedType.LPStr)] [In] string pszFilePath, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash);
        [PreserveSig]
        int GetHashFromFileW([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash);
        [PreserveSig]
        int GetHashFromHandle([In] IntPtr hFile, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash);
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.U4)]
        int StrongNameCompareAssemblies([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzAssembly1, [MarshalAs(UnmanagedType.LPWStr)] [In] string pwzAssembly2, [MarshalAs(UnmanagedType.U4)] out int dwResult);
        [PreserveSig]
        int StrongNameFreeBuffer([In] IntPtr pbMemory);
        [PreserveSig]
        int StrongNameGetBlob([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] [Out] byte[] pbBlob, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int pcbBlob);
        [PreserveSig]
        int StrongNameGetBlobFromImage([In] IntPtr pbBase, [MarshalAs(UnmanagedType.U4)] [In] int dwLength, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbBlob, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int pcbBlob);
        [PreserveSig]
        int StrongNameGetPublicKey([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] [In] byte[] pbKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbKeyBlob, out IntPtr ppbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbPublicKeyBlob);
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.U4)]
        int StrongNameHashSize([MarshalAs(UnmanagedType.U4)] [In] int ulHashAlg, [MarshalAs(UnmanagedType.U4)] out int cbSize);
        [PreserveSig]
        int StrongNameKeyDelete([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer);
        [PreserveSig]
        int StrongNameKeyGen([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.U4)] [In] int dwFlags, out IntPtr ppbKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbKeyBlob);
        [PreserveSig]
        int StrongNameKeyGenEx([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.U4)] [In] int dwFlags, [MarshalAs(UnmanagedType.U4)] [In] int dwKeySize, out IntPtr ppbKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbKeyBlob);
        [PreserveSig]
        int StrongNameKeyInstall([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] [In] byte[] pbKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbKeyBlob);
        [PreserveSig]
        int StrongNameSignatureGeneration([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [In] byte[] pbKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbKeyBlob, [In] [Out] IntPtr ppbSignatureBlob, [MarshalAs(UnmanagedType.U4)] out int pcbSignatureBlob);
        [PreserveSig]
        int StrongNameSignatureGenerationEx([MarshalAs(UnmanagedType.LPWStr)] [In] string wszFilePath, [MarshalAs(UnmanagedType.LPWStr)] [In] string wszKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [In] byte[] pbKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbKeyBlob, [In] [Out] IntPtr ppbSignatureBlob, [MarshalAs(UnmanagedType.U4)] out int pcbSignatureBlob, [MarshalAs(UnmanagedType.U4)] [In] int dwFlags);
        [PreserveSig]
        int StrongNameSignatureSize([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] [In] byte[] pbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbSize);
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.U4)]
        int StrongNameSignatureVerification([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.U4)] [In] int dwInFlags, [MarshalAs(UnmanagedType.U4)] out int dwOutFlags);
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.U4)]
        int StrongNameSignatureVerificationEx([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.I1)] [In] bool fForceVerification, [MarshalAs(UnmanagedType.I1)] out bool fWasVerified);
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.U4)]
        int StrongNameSignatureVerificationFromImage([In] IntPtr pbBase, [MarshalAs(UnmanagedType.U4)] [In] int dwLength, [MarshalAs(UnmanagedType.U4)] [In] int dwInFlags, [MarshalAs(UnmanagedType.U4)] out int dwOutFlags);
        [PreserveSig]
        int StrongNameTokenFromAssembly([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, out IntPtr ppbStrongNameToken, [MarshalAs(UnmanagedType.U4)] out int pcbStrongNameToken);
        [PreserveSig]
        int StrongNameTokenFromAssemblyEx([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, out IntPtr ppbStrongNameToken, [MarshalAs(UnmanagedType.U4)] out int pcbStrongNameToken, out IntPtr ppbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbPublicKeyBlob);

        int StrongNameTokenFromPublicKey([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] [In] byte[] pbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbPublicKeyBlob, out IntPtr ppbStrongNameToken, [MarshalAs(UnmanagedType.U4)] out int pcbStrongNameToken);
    }  
}

Ссылки:

Checking For A Valid Strong Name Signature

Checking an assembly for a strong name

READ ALSO
Парсинг сайта metanit

Парсинг сайта metanit

Хочу спарсить сайт metanitcom

302
Использование статических библиотек (C++) в С# и Python

Использование статических библиотек (C++) в С# и Python

Можете ли вы пояснить мне, возможно ли использование статических библиотек, написанных на C++, в приложениях на C# и PythonВо время компиляции...

235
Сохранение состояния radiobutton c#

Сохранение состояния radiobutton c#

У меня в программе есть Combobox с четырьмя значениями и четыре radiobutton'aМне нужно выбрать первый элемент в combobox, нажать на нужные radiobutton'ы, выбрать...

302