Je voudrais vérifier par programme si un fichier a été signé numériquement ou non.
Pour l'instant, j'ai trouvé un assez obscur code dans MSDN , qui ne compile pas ...
Une idée sur le sujet?
Soit dit en passant, un outil externe avec ligne de commande serait également formidable.
La partie manquante importante de la réponse mentionnant signtool est:
Oui, avec le bien connu signtool.exe, vous pouvez également savoir si un fichier est signé. Pas besoin de télécharger un autre outil!
Par exemple. avec la ligne simple:
signtool verify /pa myfile.exe
if %ERRORLEVEL% GEQ 1 echo This file is not signed.
(Pour une sortie verbeuse, ajoutez un '/ v' après '/ pa'.)
On peut se demander: pourquoi c'est important? Je viens de signer les fichiers (à nouveau) qui doivent être signés et ça marche.
Mon objectif est de garder les builds propres et de ne pas signer de fichiers une seconde fois car non seulement la date est modifiée, mais c'est binaire différent après cela.
Exemple d'entreprise: mon client a un processus de génération et de post-construction automatisé et simplifié. Il existe plusieurs sources pour différents ensembles de fichiers, et à la fin tout est construit, testé et intégré à la distribution - et pour cela, certains fichiers doivent être signés. Pour garantir que certains fichiers ne quittent pas l'unité sans être signés, nous avions l'habitude de signer tous les fichiers importants, même s'ils étaient déjà signés.
Mais ce n'est pas assez propre:
1) Si nous signons à nouveau un fichier, qui est déjà signé, la date du fichier et l'empreinte binaire changent, et le fichier perd sa comparabilité avec ses sources, s'il était simplement copié. (Au moins si vous signez avec un horodatage, ce que nous faisons toujours et je pense que c'est fortement recommandé.)
Il s'agit d'une grave perte de qualité, car ce fichier n'est plus comparable à ses prédécesseurs d'autres sources de fichiers.
2) Si nous signons à nouveau un fichier, cela pourrait également être un défaut et il s'agit d'un fichier tiers qui ne devrait pas être signé par votre unité.
Vous pouvez éviter les deux en rendant la signature elle-même conditionnelle en fonction du code de retour de l'appel "signtool verify" précédent mentionné.
Télécharger Sigcheck y utilisez la commande suivante.
sigcheck.exe -a -u -e
Un exemple de DLL signée
Un exemple de DLL non signée
Sigcheck est un utilitaire de ligne de commande qui affiche le numéro de version du fichier. Bonne chance
Si vous avez besoin d'un outil externe, vous pouvez utiliser signtool.exe. Il fait partie du SDK Windows, il prend des arguments de ligne de commande, et vous pouvez en savoir plus ici, http://msdn.Microsoft.com/en-us/library/aa387764.aspx
J'ai trouvé une autre option (code .Net pur) sur le web ici .
Le code est très simple et fonctionne.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
string filePath = args[0];
if (!File.Exists(filePath))
{
Console.WriteLine("File not found");
return;
}
X509Certificate2 theCertificate;
try
{
X509Certificate theSigner = X509Certificate.CreateFromSignedFile(filePath);
theCertificate = new X509Certificate2(theSigner);
}
catch (Exception ex)
{
Console.WriteLine("No digital signature found: " + ex.Message);
return;
}
bool chainIsValid = false;
/*
*
* This section will check that the certificate is from a trusted authority IE
* not self-signed.
*
*/
var theCertificateChain = new X509Chain();
theCertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
/*
*
* Using .Online here means that the validation WILL CALL OUT TO THE INTERNET
* to check the revocation status of the certificate. Change to .Offline if you
* don't want that to happen.
*/
theCertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
theCertificateChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
theCertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
chainIsValid = theCertificateChain.Build(theCertificate);
if (chainIsValid)
{
Console.WriteLine("Publisher Information : " + theCertificate.SubjectName.Name);
Console.WriteLine("Valid From: " + theCertificate.GetEffectiveDateString());
Console.WriteLine("Valid To: " + theCertificate.GetExpirationDateString());
Console.WriteLine("Issued By: " + theCertificate.Issuer);
}
else
{
Console.WriteLine("Chain Not Valid (certificate is self-signed)");
}
}
}
}
Vous pouvez également essayer d'utiliser le package npm sign-check
à cet effet.
Ce package implémente l'API WinVerifyTrust et a une utilisation simple:
npm install -g sign-check
sign-check 'path/to/file'