2016-09-16 6 views
4

Lors de la signature de mon déploiement ClickOnce via la page des paramètres "Signing" du projet Visual Studio, j'ai spécifié notre certificat Authenticode SHA2 (SHA256) et publié.Comment signer Authenticode Déployer ClickOnce avec un certificat EV SHA2 et éviter "Unknown Publisher"

enter image description here

Après la publication et de tenter d'exécuter le programme d'amorçage (setup.exe) Je suis présenté avec le « Editeur inconnu » dans la boîte de dialogue ClickOnce.

enter image description here

Le certificat EV en question est valide et en cours d'exécution sur un jeton matériel eToken avec des outils clients SafeNet pour communiquer avec le jeton. La signature régulière de fichiers PE (exe et dll) avec signtool produit toujours des assemblages parfaitement valides et l'éditeur est connu. Ceci est seulement un problème avec les déploiements ClickOnce. En outre, les fichiers individuels du déploiement ClickOnce semblent parfaitement valides car l'onglet des signatures numériques de la boîte de dialogue des propriétés du fichier est répertorié correctement pour le programme d'amorçage (setup.exe) et les fichiers d'assemblage avec le suffixe ".deploy".

enter image description here

En outre, le ".Application" et les fichiers ".manifest" sont correctement mutées (probablement via Visual Studio par mage) pour contenir l'élément <publisherIdentity> avec l'algorithme correctement réglé.

enter image description here

La machine de signature est en cours d'exécution Win10 et j'ai essayé toutes les permutations que je pouvais imaginer:

  • avec et sans horodatage
  • Avec et sans nom fort signature
  • Avec et sans publication en ligne
  • Avec et sans publication en ligne https
  • Avec et sans "emplacement de mise à jour" spécifique via Publish la page
  • avec et sans "Nom de l'éditeur" set via Description dans page Publier
  • Avec toutes les combinaisons d'options Manifest:
    • Excluez URL fournisseur déploiement
    • l'application de bloc d'être activé via une URL
    • utilisation manifeste d'application pour les informations de confiance
  • machi multiples nda sur différentes versions de signature manifeste manuel de Windows
  • et signature assemblage par mage et signtool (oui mageui aussi bien)
  • Assurez-vous que le certificat n'est pas révoqué avec le fournisseur de certificat

Il semble y avoir someone else experiencing this.

Répondre

2

La raison pour laquelle cela se produit est due à deux facteurs:

  1. ClickOnce affiche "Editeur inconnu" lorsque vous utilisez un certificat Authenticode SHA2.
  2. Le 1er janvier 2016, Windows a désapprouvé SHA1 pour la signature/signature de code Authenticode. La technologie Windows SmartScreen affiche donc "Publisher inconnu" lors de l'utilisation d'un certificat SHA1 Authenticode.

Ceci est en effet un fourre-22, vous avez besoin SHA1 pour la vérification de l'éditeur ClickOnce et SHA2 pour SmartScreen. Nice.

Travaillez avec votre fournisseur de certificats (je l'espère un véritable CA) pour vous obtenir un SHA1 et certificat SHA2. Les gens de DigiCert étaient super. Vous devez travailler avec votre autorité de certification dans la plupart des cas car même si vous avez déjà votre propre certificat SHA2 et que vous travaillez avec eux pour obtenir également un certificat SHA1 (ou vice versa), il annulera automatiquement tous les certificats existants avec eux. . Dans le cas de DigiCert, ils ont pu empêcher la révocation automatique lorsque j'ai expliqué ce que je voulais essayer (double signature). Une fois que vous avez installé ceux sur votre jeton EV, configurez Visual Studio pour signer vos manifestes ClickOnce avec votre certificat SHA1.

Après avoir installé ceux sur votre jeton EV, configurez Visual Studio pour signer vos manifestes ClickOnce avec votre certificat SHA1. Idéalement, vous devez également fournir un serveur Timestamp dans cette même boîte de dialogue pour l'expiration de votre certificat.

enter image description here

Après la publication de votre déploiement ClickOnce localement et avant de distribuer, à double signer ClickOnce bootstrapper (setup.exe) par votre certificat de annexant SHA2.

signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /as /sha1 YourCertThumbprintHash "X:\Deployment\ClickOnceCert\setup.exe" 

Note, une façon de trouver votre empreinte cert est via le certificat composant logiciel enfichable MMC. Et oui, les empreintes digitales sont censées être SHA1 pour les certificats SHA2.

enter image description here

Maintenant, la bootstapper montre à la fois de vos certificats dans l'onglet Signatures numériques de la boîte de dialogue des propriétés du fichier.

enter image description here

Lorsque vous exécutez le fichier setup.exe à partir de l'emplacement spécifié comme « URL du dossier d'installation » de votre page Publier dans Visual Studio, vous devriez voir l'éditeur comme digne de confiance. Il est important de comprendre le dossier d'installation car si vous deviez exécuter l'application à partir d'un autre emplacement, attendez pour ne pas être approuvé car le programme d'amorçage appelle le dossier d'installation connu pour récupérer les fichiers d'application.

enter image description here

+0

j'ai essayé de suivre ces instructions. J'ai contacté COMODO, qui a émis mon certificat SHA2 EV il y a environ un mois. Ils ont dit: "Nous n'émettons plus de certificats SHA1". Il était clair que je discutais avec un fonctionnaire qui n'avait pas la capacité d'intensifier le problème. Je n'ai aucune idée de ce qu'il faut faire ensuite. –

+0

@RobPerkins un peu vieux, mais avez-vous fait des progrès à ce sujet? Je suis dans la même situation avec un certificat GlobalSign EV sur un token USB ... –

+0

Rien. Je devrais passer par le processus coûteux d'utiliser un fournisseur de cert qui produira les deux types de certs. Ça ne vaut pas le coup maintenant. –

1

La réponse marquée, pour moi en tout cas, les résultats dans un écran d'avertissement intelligent. Vous pouvez être intéressé par le script PowerShell que j'ai écrit, qui corrige les deux problèmes en signant ce qu'il peut avec un certificat SHA256, puis les fichiers ClickOnce (.application) avec un certificat SHA1.

SignClickOnceApp.ps1

code

au moment de l'affichage

<# 
.SYNOPSIS 
    A PowerShell Script to correctly sign a ClickOnce Application. 
.DESCRIPTION 
    Microsoft ClickOnce Applications Signed with a SHA256 Certificate show as Unknown Publisher during installation, ClickOnce Applications signed with a SHA1 Certificate show an Unknown Publisher SmartScreen Warning once installed, this happens because: 
    1) The ClickOnce installer only supports SHA1 certificates (not SHA256), but, 
    2) Microsoft has depreciated SHA1 for Authenticode Signing. 

    This script uses two code signing certificates (one SHA1 and one SHA256) to sign the various parts of the ClickOnce Application so that both the ClickOnce Installer and SmartScreen are happy. 
.PARAMETER VSRoot 
    The Visual Studio Projects folder, if not provided .\Documents\Visual Studio 2015\Projects will be assumed 
.PARAMETER SolutionName 
    The Name of the Visual Studio Solution (Folder), if not provided the user is prompted. 
.PARAMETER ProjectName 
    The Name of the Visual Studio Project (Folder), if not provided the user is prompted. 
.PARAMETER SHA1CertThumbprint 
    The Thumbprint of the SHA1 Code Signing Certificate, if not provided the user is prompted. 
.PARAMETER SHA256CertThumbprint 
    The Thumbprint of the SHA256 Code Signing Certificate, if not provided the user is prompted. 
.PARAMETER TimeStampingServer 
    The Time Stamping Server to be used while signing, if not provided the user is prompted. 
.PARAMETER PublisherName 
    The Publisher to be set on the ClickOnce files, if not provided the user is prompted. 
.PARAMETER Verbose 
    Writes verbose output. 
.EXAMPLE 
    SignClickOnceApp.ps1 -VSRoot "C:\Users\Username\Documents\Visual Studio 2015\Projects" -SolutionName "MySolution" -ProjectName "MyProject" -SHA1CertThumbprint "f3f33ccc36ffffe5baba632d76e73177206143eb" -SHA256CertThumbprint "5d81f6a4e1fb468a3b97aeb3601a467cdd5e3266" -TimeStampingServer "http://time.certum.pl/" -PublisherName "Awesome Software Inc." 
    Signs MyProject in MySolution which is in C:\Users\Username\Documents\Visual Studio 2015\Projects using the specified certificates, with a publisher of "Awesome Software Inc." and the Certum Timestamping Server. 
.NOTES 
    Author : Joe Pitt 
    License : SignClickOnceApp by Joe Pitt is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/. 
.LINK 
    https://www.joepitt.co.uk/Project/SignClickOnceApp/ 
#> 
param (
    [string]$VSRoot, 
    [string]$SolutionName, 
    [string]$ProjectName, 
    [string]$SHA1CertThumbprint, 
    [string]$SHA256CertThumbprint, 
    [string]$TimeStampingServer, 
    [string]$PublisherName, 
    [switch]$Verbose 
) 

$oldverbose = $VerbosePreference 
if($Verbose) 
{ 
    $VerbosePreference = "continue" 
} 

# Visual Studio Root Path 
if(!$PSBoundParameters.ContainsKey('VSRoot')) 
{ 
    $VSRoot = '.\Documents\Visual Studio 2015\Projects\' 
} 
if (Test-Path "$VSRoot") 
{ 
    Write-Verbose "Using '$VSRoot' for Visual Studio Root" 
} 
else 
{ 
    Write-Error -Message "VSRoot does not exist." -RecommendedAction "Check path and try again" -ErrorId "1" ` 
     -Category ObjectNotFound -CategoryActivity "Testing VSRoot Path" -CategoryReason "The VSRoot path was not found" ` 
     -CategoryTargetName "$VSRoot" -CategoryTargetType "Directory" 
    exit 1 
} 

# Solution Path 
if(!$PSBoundParameters.ContainsKey('SolutionName')) 
{ 
    $SolutionName = Read-Host "Solution Name" 
} 
if (Test-Path "$VSRoot\$SolutionName") 
{ 
    Write-Verbose "Using '$VSRoot\$SolutionName' for Solution Path" 
    $SolutionPath = "$VSRoot\$SolutionName" 
} 
else 
{ 
    Write-Error -Message "Solution does not exist." -RecommendedAction "Check Solution Name and try again" -ErrorId "2" ` 
     -Category ObjectNotFound -CategoryActivity "Testing Solution Path" -CategoryReason "The Solution path was not found" ` 
     -CategoryTargetName "$VSRoot\$SolutionName" -CategoryTargetType "Directory" 
    exit 2 
} 

# Project Path 
if(!$PSBoundParameters.ContainsKey('ProjectName')) 
{ 
    $ProjectName = Read-Host "Project Name" 
} 
if (Test-Path "$SolutionPath\$ProjectName") 
{ 
    Write-Verbose "Using '$SolutionPath\$ProjectName' for Project Path" 
    $ProjectPath = "$SolutionPath\$ProjectName" 
} 
else 
{ 
    Write-Error -Message "Project does not exist." -RecommendedAction "Check Project Name and try again" -ErrorId "3" ` 
     -Category ObjectNotFound -CategoryActivity "Testing Project Path" -CategoryReason "The Project path was not found" ` 
     -CategoryTargetName "$SolutionPath\$ProjectName" -CategoryTargetType "Directory" 
    exit 3 
} 

# Publish Path 
if (Test-Path "$ProjectPath\publish") 
{ 
    Write-Verbose "Using '$ProjectPath\publish' for Publish Path" 
    $PublishPath = "$ProjectPath\publish" 
} 
else 
{ 
    Write-Error -Message "Publish path does not exist." -RecommendedAction "Check Project has been published to \publish and try again" -ErrorId "4" ` 
     -Category ObjectNotFound -CategoryActivity "Testing Publish Path" -CategoryReason "The publish path was not found" ` 
     -CategoryTargetName "$ProjectPath\publish" -CategoryTargetType "Directory" 
    exit 4 
} 

# Application Files Path 
if (Test-Path "$PublishPath\Application Files") 
{ 
    Write-Verbose "Using '$PublishPath\Application Files' for Application Files Path" 
    $AppFilesPath = "$PublishPath\Application Files" 
} 
else 
{ 
    Write-Error -Message "Application Files path does not exist." -RecommendedAction "Check Project has been published to \publish and try again" -ErrorId "5" ` 
     -Category ObjectNotFound -CategoryActivity "Testing Application Files Path" -CategoryReason "The Application Files path was not found" ` 
     -CategoryTargetName "$PublishPath\Application Files" -CategoryTargetType "Directory" 
    exit 5 
} 

# Target Path 
$TargetPath = Convert-Path "$AppFilesPath\${ProjectName}_*" 
if ($($TargetPath.Length) -ne 0) 
{ 
    Write-Verbose "Using $TargetPath for Target Path" 
} 
else 
{ 
    Write-Error -Message "No versions." -RecommendedAction "Check Project has been published to \publish and try again" -ErrorId "6" ` 
     -Category ObjectNotFound -CategoryActivity "Searching for published version path" -CategoryReason "No Application has been published using ClickOnce" ` 
     -CategoryTargetName "$AppFilesPath\${ProjectName}_*" -CategoryTargetType "Directory" 
    exit 6 
} 

# SHA1 Certificate 
if(!$PSBoundParameters.ContainsKey('SHA1CertThumbprint')) 
{ 
    $SHA1CertThumbprint = Read-Host "SHA1 Certificate Thumbprint" 
} 
if ("$SHA1CertThumbprint" -notmatch "^[0-9A-Fa-f]{40}$") 
{ 
    Write-Error -Message "SHA1 Thumbprint Malformed" -RecommendedAction "Check the thumbprint and try again" -ErrorId "7" ` 
     -Category InvalidArgument -CategoryActivity "Verifying Thumbprint Format" -CategoryReason "Thumbprint is not a 40 character Base64 string" ` 
     -CategoryTargetName "$SHA1CertThumbprint" -CategoryTargetType "Base64String" 
    exit 7 
} 
$SHA1Found = Get-ChildItem -Path Cert:\CurrentUser\My | where {$_.Thumbprint -eq "$SHA1CertThumbprint"} | Measure-Object 
if ($SHA1Found.Count -eq 0) 
{ 
    Write-Error -Message "SHA1 Certificate Not Found" -RecommendedAction "Check the thumbprint and try again" -ErrorId "8" ` 
     -Category ObjectNotFound -CategoryActivity "Searching for certificate" -CategoryReason "Certificate with Thumbprint not found" ` 
     -CategoryTargetName "$SHA1CertThumbprint" -CategoryTargetType "Base64String" 
    exit 8 
} 

# SHA256 Certificate 
if(!$PSBoundParameters.ContainsKey('SHA256CertThumbprint')) 
{ 
    $SHA256CertThumbprint = Read-Host "SHA256 Certificate Thumbprint" 
} 
if ("$SHA256CertThumbprint" -notmatch "^[0-9A-Fa-f]{40}$") 
{ 
    Write-Error -Message "SHA256 Thumbprint Malformed" -RecommendedAction "Check the thumbprint and try again" -ErrorId "9" ` 
     -Category InvalidArgument -CategoryActivity "Verifying Thumbprint Format" -CategoryReason "Thumbprint is not a 40 character Base64 string" ` 
     -CategoryTargetName "$SHA256CertThumbprint" -CategoryTargetType "Base64String" 
    exit 9 
} 
$SHA256Found = Get-ChildItem -Path Cert:\CurrentUser\My | where {$_.Thumbprint -eq "$SHA256CertThumbprint"} | Measure-Object 
if ($SHA256Found.Count -eq 0) 
{ 
    Write-Error -Message "SHA256 Certificate Not Found" -RecommendedAction "Check the thumbprint and try again" -ErrorId "10" ` 
     -Category ObjectNotFound -CategoryActivity "Searching for certificate" -CategoryReason "Certificate with Thumbprint not found" ` 
     -CategoryTargetName "$SHA256CertThumbprint" -CategoryTargetType "Base64String" 
    exit 10 
} 

# TimeStamping Server 
if(!$PSBoundParameters.ContainsKey('TimeStampingServer')) 
{ 
    $TimeStampingServer = Read-Host "TimeStamping Server URL" 
} 
if ("$TimeStampingServer" -notmatch "^http(s)?:\/\/[A-Za-z0-9-._~:/?#[\]@!$&'()*+,;=]+$") 
{ 
    Write-Error -Message "SHA256 Thumbprint Malformed" -RecommendedAction "Check the TimeStamp URL and try again" -ErrorId "11" ` 
     -Category InvalidArgument -CategoryActivity "Verifying TimeStamping URL" -CategoryReason "TimeStamping URL is not a RFC Compliant URL" ` 
     -CategoryTargetName "$TimeStampingServer" -CategoryTargetType "URL" 
    exit 11 
} 

# Publisher Name 
# Project Path 
if(!$PSBoundParameters.ContainsKey('PublisherName')) 
{ 
    $PublisherName = Read-Host "Publisher Name" 
} 

# Sign setup.exe and application.exe with SHA256 Cert 
Write-Verbose "Signing '$PublishPath\Setup.exe' (SHA256)" 
Start-Process "$PSScriptRoot\signtool.exe" -ArgumentList "sign /fd SHA256 /td SHA256 /tr $TimeStampingServer /sha1 $SHA256CertThumbprint `"$PublishPath\Setup.exe`"" -Wait -NoNewWindow 
Write-Verbose "Signing '$TargetPath\$ProjectName.exe.deploy' (SHA256)" 
Start-Process "$PSScriptRoot\signtool.exe" -ArgumentList "sign /fd SHA256 /td SHA256 /tr $TimeStampingServer /sha1 $SHA256CertThumbprint `"$TargetPath\$ProjectName.exe.deploy`"" -Wait -NoNewWindow 

# Remove .deploy extensions 
Write-Verbose "Removing .deploy extensions" 
Get-ChildItem "$TargetPath\*.deploy" -Recurse | Rename-Item -NewName { $_.Name -replace '\.deploy','' } 

# Sign Manifest with SHA256 Cert 
Write-Verbose "Signing '$TargetPath\$ProjectName.exe.manifest' (SHA256)" 
Start-Process "$PSScriptRoot\mage.exe" -ArgumentList "-update `"$TargetPath\$ProjectName.exe.manifest`" -ch $SHA256CertThumbprint -if `"Logo.ico`" -ti `"$TimeStampingServer`"" -Wait -NoNewWindow 

# Sign ClickOnces with SHA1 Cert 
Write-Verbose "Signing '$TargetPath\$ProjectName.application' (SHA1)" 
Start-Process "$PSScriptRoot\mage.exe" -ArgumentList "-update `"$TargetPath\$ProjectName.application`" -ch $SHA1CertThumbprint -appManifest `"$TargetPath\$ProjectName.exe.manifest`" -pub `"$PublisherName`" -ti `"$TimeStampingServer`"" -Wait -NoNewWindow 
Write-Verbose "Signing '$PublishPath\$ProjectName.application' (SHA1)" 
Start-Process "$PSScriptRoot\mage.exe" -ArgumentList "-update `"$PublishPath\$ProjectName.application`" -ch $SHA1CertThumbprint -appManifest `"$TargetPath\$ProjectName.exe.manifest`" -pub `"$PublisherName`" -ti `"$TimeStampingServer`"" -Wait -NoNewWindow 

# Readd .deply extensions 
Write-Verbose "Re-adding .deploy extensions" 
Get-ChildItem -Path "$TargetPath\*" -Recurse | Where-Object {!$_.PSIsContainer -and $_.Name -notlike "*.manifest" -and $_.Name -notlike "*.application"} | Rename-Item -NewName {$_.Name + ".deploy"} 
+0

Pourriez-vous copier la source PowerShell dans cette réponse avec le lien si le lien disparaît (aussi [ici]) (http://stackoverflow.com/questions/25004056/resign-clickonce-manifest-using-mage-exe/39811422 # 39811422))? Cela améliore la réponse. En outre, vous ne devriez pas recevoir d'avertissement SmartScreen suite à ma réponse tant que votre fichier setup.exe ClickOnce a été signé avec un certificat SHA256 ** valide **. Bienvenue à SO, belle contribution !! –

+0

@AdamCaviness Code actuel ajouté comme demandé. Ref un SHA2 signé setup.exe, ceci n'est vrai que si l'utilisateur utilise setup.exe, s'ils utilisent simplement AppName.application alors un avertissement de certificat est affiché. –