{"id":23009605,"url":"https://github.com/devolutions/devolutions-authenticode","last_synced_at":"2025-04-22T23:50:42.618Z","repository":{"id":43023335,"uuid":"469792156","full_name":"Devolutions/devolutions-authenticode","owner":"Devolutions","description":"Devolutions Authenticode Signing","archived":false,"fork":false,"pushed_at":"2023-12-20T20:40:54.000Z","size":73,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-01-07T15:01:40.771Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Devolutions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-14T15:25:48.000Z","updated_at":"2024-10-28T16:58:10.000Z","dependencies_parsed_at":"2025-02-08T06:44:05.408Z","dependency_job_id":"3ab5ce32-76e1-4a08-b1cb-8f7f773bb8a4","html_url":"https://github.com/Devolutions/devolutions-authenticode","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fdevolutions-authenticode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fdevolutions-authenticode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fdevolutions-authenticode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fdevolutions-authenticode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Devolutions","download_url":"https://codeload.github.com/Devolutions/devolutions-authenticode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250343909,"owners_count":21415037,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["architecture"],"created_at":"2024-12-15T09:15:06.374Z","updated_at":"2025-04-22T23:50:42.596Z","avatar_url":"https://github.com/Devolutions.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zip Authenticode\n\nDo you already sign .msi, .exe, .dll, .ps1 and .cab files with Authenticode and just wish there was a simple way to make it work for .zip files? Look no further! Taking inspiration from the [zipsign](https://github.com/falk-werner/zipsign) project, we have adapted Authenticode to the zip file format in a way that leverages the existing Windows APIs for signing and validation.\n\n## Bootstrap Test CA\n\nDon't want to bother creating your own test certificate authority? Just bootstrap the test certificate authority and code signing certificate we have prepared. Please keep in mind that it is strictly meant for testing and should not be used in production. Run the following in an elevated shell:\n\n```powershell\n$AuthenticodePath = \"~\\Documents\\Authenticode\"\nNew-Item -ItemType Directory -Path $AuthenticodePath -ErrorAction SilentlyContinue | Out-Null\n\n$TestCertsUrl = \"https://raw.githubusercontent.com/Devolutions/devolutions-authenticode/master/data/certs\"\n@('authenticode-test-ca.crt','authenticode-test-cert.pfx') | ForEach-Object {\n    Invoke-WebRequest -Uri \"$TestCertsUrl/$_\" -OutFile $AuthenticodePath\\$_\n}\n\nImport-Certificate -FilePath \"$AuthenticodePath\\authenticode-test-ca.crt\" -CertStoreLocation \"cert:\\LocalMachine\\Root\"\n\n$CodeSignPassword = ConvertTo-SecureString \"CodeSign123!\" -AsPlainText -Force\nImport-PfxCertificate -FilePath \"$AuthenticodePath\\authenticode-test-cert.pfx\" -CertStoreLocation 'cert:\\CurrentUser\\My' -Password $CodeSignPassword\n```\n\nCode signing operations with most tools require that the CA be present in the machine trusted root certificate authorities. Run the following in an elevated shell to remove all test certificates once you no longer need them:\n\n```powershell\nGet-ChildItem cert:\\LocalMachine\\Root | Where-Object { $_.Subject -eq \"CN=Devolutions Authenticode Test CA\" } | Remove-Item\nGet-ChildItem cert:\\CurrentUser\\My | Where-Object { $_.Subject -eq \"CN=Test Code Signing Certificate\" } | Remove-Item\n```\n\n## Self-signed Certificate\n\nStart by creating a simple self-signed certificate for Authenticode code signing:\n\n```powershell\n$params = @{\n    Subject = 'CN=ZipAuthenticode'\n    Type = 'CodeSigning'\n    CertStoreLocation = 'cert:\\CurrentUser\\My'\n    HashAlgorithm = 'SHA256'\n}\n$cert = New-SelfSignedCertificate @params\n```\n\nFind the certificate in the current user store, export it to a file without the private key, and import it into the system trusted root CAs (requires an elevated shell):\n\n```powershell\n$cert = @(Get-ChildItem cert:\\CurrentUser\\My -CodeSigning | Where-Object { $_.Subject -eq \"CN=ZipAuthenticode\" })[0]\n$cert | Export-Certificate -FilePath \"~\\Documents\\ZipAuthenticode.crt\"\nImport-Certificate -FilePath \"~\\Documents\\ZipAuthenticode.crt\" -CertStoreLocation \"cert:\\LocalMachine\\Root\"\n```\n\nKeep a one-liner command to obtain the correct certificate for code signing, as you will likely need it more than once. This command filters for code signing certificates in the current user certificate store that use the \"ZipAuthenticode\" subject name. You can also use the thumbprint to uniquely identify the certificate easily.\n\n```powershell\nPS C:\\\u003e $cert = @(Get-ChildItem cert:\\CurrentUser\\My -CodeSigning | Where-Object { $_.Subject -eq \"CN=ZipAuthenticode\" })[0]\nPS C:\\\u003e $cert\n\n   PSParentPath: Microsoft.PowerShell.Security\\Certificate::CurrentUser\\My\n\nThumbprint                                Subject              EnhancedKeyUsageList\n----------                                -------              --------------------\n6256DFDA7528DF20730950A4D9DC0727CE7EA404  CN=ZipAuthenticode   Code Signing\n```\n\n## Private Certificate Authority\n\nCreate a test certificate authority:\n\n```powershell\n$NotBefore = Get-Date\n$BasicConstraints = \"2.5.29.19={text}ca=true\u0026pathLength=1\"\n$ExtendedKeyUsage = \"2.5.29.37={text}1.3.6.1.5.5.7.3.3,1.3.6.1.5.5.7.3.8\"\n$TextExtension = @($BasicConstraints,$ExtendedKeyUsage)\n$params = @{\n    Subject = 'CN=Devolutions Authenticode Test CA'\n    CertStoreLocation = 'cert:\\CurrentUser\\My'\n    KeyExportPolicy = 'Exportable'\n    KeyLength = 2048\n    KeyUsage = 'CertSign','DigitalSignature'\n    KeyUsageProperty = 'All'\n    KeyAlgorithm = 'RSA'\n    HashAlgorithm = 'SHA256'\n    TextExtension = $TextExtension\n    NotBefore = $NotBefore\n    NotAfter = $NotBefore.AddYears(10)\n}\n$RootCA = New-SelfSignedCertificate @params\n$RootPassword = ConvertTo-SecureString \"Root123!\" -AsPlainText -Force\n$RootCA | Export-Certificate -FilePath \"~\\Documents\\authenticode-test-ca.crt\"\n$RootCA | Export-PfxCertificate -FilePath \"~\\Documents\\authenticode-test-ca.pfx\" -Password $RootPassword\n```\n\nCreate a test code signing certificate signed by the test certificate authority:\n\n```powershell\n$NotBefore = Get-Date\n$RootCA = @(Get-ChildItem cert:\\CurrentUser\\My | Where-Object { $_.Subject -eq \"CN=Devolutions Authenticode Test CA\" })[0]\n$params = @{\n    Signer = $RootCA\n    Type = 'CodeSigning'\n    Subject = 'CN=Test Code Signing Certificate'\n    CertStoreLocation = 'cert:\\CurrentUser\\My'\n    KeyExportPolicy = 'Exportable'\n    KeyLength = 2048\n    KeyUsage = 'DigitalSignature'\n    KeyAlgorithm = 'RSA'\n    HashAlgorithm = 'SHA256'\n    NotBefore = $NotBefore\n    NotAfter = $NotBefore.AddYears(5)\n}\n$CodeSignCert = New-SelfSignedCertificate @params\n$CodeSignPassword = ConvertTo-SecureString \"CodeSign123!\" -AsPlainText -Force\n$CodeSignCert | Export-PfxCertificate -FilePath \"~\\Documents\\authenticode-test-cert.pfx\" -Password $CodeSignPassword\n```\n\nRemove the test certificate authority and its private key from the current user certificate store. You can always re-import it later to create new code signing certificates:\n\n```powershell\n@(Get-ChildItem cert:\\CurrentUser\\My | Where-Object { $_.Subject -eq \"CN=Devolutions Authenticode Test CA\" })[0] | Remove-Item\n$RootCA | Remove-Item\n```\n\nIf you need to sign a new code signing certificate, you will need to re-import the certificate authority and its private key:\n\n```powershell\n$RootPassword = ConvertTo-SecureString \"Root123!\" -AsPlainText -Force\n$RootCA = Import-PfxCertificate -FilePath \"~\\Documents\\authenticode-test-ca.pfx\" -CertStoreLocation 'cert:\\CurrentUser\\My' -Password $RootPassword\n```\n\nImport the test certificate authority without the private key into the machine trusted root CAs using an elevated shell to trust it:\n\n```powershell\nImport-Certificate -FilePath \"~\\Documents\\authenticode-test-ca.crt\" -CertStoreLocation \"cert:\\LocalMachine\\Root\"\n```\n\nObtain a reference to the code siging certificate from the current user store:\n\n```powershell\nPS C:\\\u003e $cert = @(Get-ChildItem cert:\\CurrentUser\\My -CodeSigning | Where-Object { $_.Subject -eq \"CN=Test Code Signing Certificate\" })[0]\nPS C:\\\u003e $cert\n\n   PSParentPath: Microsoft.PowerShell.Security\\Certificate::CurrentUser\\My\n\nThumbprint                                Subject              EnhancedKeyUsageList\n----------                                -------              --------------------\nF9BEF87E6458FD90C7E22B27D6FF0221559A590F  CN=Test Code Signin… Code Signing\n```\n\nThat's it!\n\n## PowerShell Module\n\nInstall the Devolutions.Authenticode PowerShell module and import it:\n\n```powershell\nInstall-Module -Name Devolutions.Authenticode\nImport-Module Devolutions.Authenticode\n```\n\nThe `Get-ZipAuthenticodeSignature` and `Set-ZipAuthenticodeSignature` PowerShell cmdlets should now be available.\n\n```powershell\nGet-Command *ZipAuthenticode*\n\nCommandType     Name                                               Version    Source\n-----------     ----                                               -------    ------\nCmdlet          Get-ZipAuthenticodeSignature                       1.0.0.0    Devolutions.Authenticode.PowerShell\nCmdlet          Set-ZipAuthenticodeSignature                       1.0.0.0    Devolutions.Authenticode.PowerShell\n```\n\n## Signing a zip file\n\nCopy a zip file into the current directory (you can use \"data\\test-unsigned.zip\") and rename it to \"test.zip\". Get the SHA256 file hash of the original file and keep it for later:\n\n```powershell\n(Get-FileHash .\\test-unsigned.zip -Algorithm SHA256) | ForEach-Object { ($_.Algorithm + ':' + $_.Hash).ToLower() }\nsha256:4667433dd582f5955e7f6355cbb2a39c5e95cbccc894c1ffaa4286f1acfed0b7\n```\n\nFetch the code signing certificate object:\n\n```powershell\n$cert = @(Get-ChildItem cert:\\CurrentUser\\My -CodeSigning | Where-Object { $_.Subject -eq \"CN=ZipAuthenticode\" })[0]\n```\n\nAnd then call `Set-ZipAuthenticodeSignature` on the zip file using the certificate:\n\n```powershell\nSet-ZipAuthenticodeSignature -Certificate $cert -TimestampServer 'http://timestamp.digicert.com' -FilePath .\\test.zip\n\nSignerCertificate      : [Subject]\n                           CN=ZipAuthenticode\n\n                         [Issuer]\n                           CN=ZipAuthenticode\n\n                         [Serial Number]\n                           1CEDD95663204A804AEA488546F1641F\n\n                         [Not Before]\n                           2022-03-12 3:10:04 PM\n\n                         [Not After]\n                           2023-03-12 4:30:04 PM\n\n                         [Thumbprint]\n                           6256DFDA7528DF20730950A4D9DC0727CE7EA404\n\nTimeStamperCertificate : [Subject]\n                           CN=DigiCert Timestamp 2021, O=\"DigiCert, Inc.\", C=US\n\n                         [Issuer]\n                           CN=DigiCert SHA2 Assured ID Timestamping CA, OU=www.digicert.com, O=DigiCert Inc, C=US\n\n                         [Serial Number]\n                           0D424AE0BE3A88FF604021CE1400F0DD\n\n                         [Not Before]\n                           2020-12-31 7:00:00 PM\n\n                         [Not After]\n                           2031-01-05 7:00:00 PM\n\n                         [Thumbprint]\n                           E1D782A8E191BEEF6BCA1691B5AAB494A6249BF3\n\nStatus                 : Valid\nStatusMessage          : Signature verified.\nPath                   : test.zip.sig.ps1\nSignatureType          : Authenticode\nIsOSBinary             : False\n```\n\nCongratulations, you have just signed your first zip file using Authenticode!\n\n## Validating Zip File Signature\n\nCall `Get-ZipAuthenticodeSignature` to object the Authenticode signature on the signed zip file:\n\n```powershell\nGet-ZipAuthenticodeSignature .\\test.zip\n\nSignerCertificate      : [Subject]\n                           CN=ZipAuthenticode\n\n                         [Issuer]\n                           CN=ZipAuthenticode\n\n                         [Serial Number]\n                           1CEDD95663204A804AEA488546F1641F\n\n                         [Not Before]\n                           2022-03-12 3:10:04 PM\n\n                         [Not After]\n                           2023-03-12 4:30:04 PM\n\n                         [Thumbprint]\n                           6256DFDA7528DF20730950A4D9DC0727CE7EA404\n\nTimeStamperCertificate : [Subject]\n                           CN=DigiCert Timestamp 2021, O=\"DigiCert, Inc.\", C=US\n\n                         [Issuer]\n                           CN=DigiCert SHA2 Assured ID Timestamping CA, OU=www.digicert.com, O=DigiCert Inc, C=US\n\n                         [Serial Number]\n                           0D424AE0BE3A88FF604021CE1400F0DD\n\n                         [Not Before]\n                           2020-12-31 7:00:00 PM\n\n                         [Not After]\n                           2031-01-05 7:00:00 PM\n\n                         [Thumbprint]\n                           E1D782A8E191BEEF6BCA1691B5AAB494A6249BF3\n\nStatus                 : Valid\nStatusMessage          : Signature verified.\nPath                   : .sig.ps1\nSignatureType          : Authenticode\nIsOSBinary             : False\n```\n\n## Zip Signature Format\n\nYou may have noticed that the reported file path in the signature object is \"test.zip.sig.ps1\" instead \"test.zip\". This file is left over from the `Set-ZipAuthenticodeSignature` operation, so let's open it to see what it contains:\n\n```\nsha256:4667433dd582f5955e7f6355cbb2a39c5e95cbccc894c1ffaa4286f1acfed0b7\n# SIG # Begin signature block\n# MIIR2AYJKoZIhvcNAQcCoIIRyTCCEcUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB\n# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR\n# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQURbYOY7I38yZeBoKx0kC3Iqp9\n# vR6ggg0/MIIDBDCCAeygAwIBAgIQHO3ZVmMgSoBK6kiFRvFkHzANBgkqhkiG9w0B\n# AQsFADAaMRgwFgYDVQQDDA9aaXBBdXRoZW50aWNvZGUwHhcNMjIwMzEyMjAxMDA0\n# WhcNMjMwMzEyMjAzMDA0WjAaMRgwFgYDVQQDDA9aaXBBdXRoZW50aWNvZGUwggEi\n# MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5eftpY1WCaq0lZ4nYd43646x/\n# rng40z/RrNFfxrAXtI1nLve5QQ75Das65xanvMjnehlXX2SweU1yy1X5tLvIeHb5\n# KED4DI03q64Cn7QqtLYFQLFmv868ZIpSB2/URPDgSYn1i7s3yoxxpCjSCZgbaR1n\n# HrwBTyDaQWbP5kLSwDo5sw4iehvXBXUmOnbknTa7N/iOy4s5bN/bJH0rtiEXQAWt\n# /EvXO4cff4za4/mCBTCbK9ZjzNDlf5t9njd9J/myalYGnSjq04QqTfeUyuZ1RqFY\n# zJWhKev/vUhUsBFtOexvz4UBYFU7WwDz4uNUiq24C09nQLhEs4OEGQ1IactZAgMB\n# AAGjRjBEMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNV\n# HQ4EFgQUCm9taG963syCKfZi5gRNYH/BBrIwDQYJKoZIhvcNAQELBQADggEBAHNC\n# e+un62MBUuR81qo+2QUvDZLa0n2LV2HX8Co7ZhFIGR9b/dUTmRfsdvh2IkUhj6B8\n# 9VObrntG0+DenZtuRpG10qM8uQMRJTY9OF2HoxPD5mK+NBOXT3oGyJFkv1hdypTR\n# c2eOfgy7ea+bNC7MrWYEonpX0z0SMXNXezYcP2LaQdMHn7P5oGnGbE0CquxYH778\n# i99Bd+EjZkkJrkPUSlh3TPZt1QCYhBGhS55csDiRGy1YkkmsiRDCowMZn355dEce\n# viGuqxYdStXHIxykN9vKcMsc26FLdPACsZKJxlAyHfAoO1wh6eQY3au6d25GUok3\n# fFvpExHPQvjBPKmGuxkwggT+MIID5qADAgECAhANQkrgvjqI/2BAIc4UAPDdMA0G\n# CSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ\n# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0\n# IFNIQTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0EwHhcNMjEwMTAxMDAwMDAw\n# WhcNMzEwMTA2MDAwMDAwWjBIMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl\n# cnQsIEluYy4xIDAeBgNVBAMTF0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIxMIIBIjAN\n# BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwuZhhGfFivUNCKRFymNrUdc6EUK9\n# CnV1TZS0DFC1JhD+HchvkWsMlucaXEjvROW/m2HNFZFiWrj/ZwucY/02aoH6Kfjd\n# K3CF3gIY83htvH35x20JPb5qdofpir34hF0edsnkxnZ2OlPR0dNaNo/Go+EvGzq3\n# YdZz7E5tM4p8XUUtS7FQ5kE6N1aG3JMjjfdQJehk5t3Tjy9XtYcg6w6OLNUj2vRN\n# eEbjA4MxKUpcDDGKSoyIxfcwWvkUrxVfbENJCf0mI1P2jWPoGqtbsR0wwptpgrTb\n# /FZUvB+hh6u+elsKIC9LCcmVp42y+tZji06lchzun3oBc/gZ1v4NSYS9AQIDAQAB\n# o4IBuDCCAbQwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/\n# BAwwCgYIKwYBBQUHAwgwQQYDVR0gBDowODA2BglghkgBhv1sBwEwKTAnBggrBgEF\n# BQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMB8GA1UdIwQYMBaAFPS2\n# 4SAd/imu0uRhpbKiJbLIFzVuMB0GA1UdDgQWBBQ2RIaOpLqwZr68KC0dRDbd42p6\n# vDBxBgNVHR8EajBoMDKgMKAuhixodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hh\n# Mi1hc3N1cmVkLXRzLmNybDAyoDCgLoYsaHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n# L3NoYTItYXNzdXJlZC10cy5jcmwwgYUGCCsGAQUFBwEBBHkwdzAkBggrBgEFBQcw\n# AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME8GCCsGAQUFBzAChkNodHRwOi8v\n# Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElEVGltZXN0\n# YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4IBAQBIHNy16ZojvOca5yAOjmdG\n# /UJyUXQKI0ejq5LSJcRwWb4UoOUngaVNFBUZB3nw0QTDhtk7vf5EAmZN7WmkD/a4\n# cM9i6PVRSnh5Nnont/PnUp+Tp+1DnnvntN1BIon7h6JGA0789P63ZHdjXyNSaYOC\n# +hpT7ZDMjaEXcw3082U5cEvznNZ6e9oMvD0y0BvL9WH8dQgAdryBDvjA4VzPxBFy\n# 5xtkSdgimnUVQvUtMjiB2vRgorq0Uvtc4GEkJU+y38kpqHNDUdq9Y9YfW5v3LhtP\n# Ex33Sg1xfpe39D+E68Hjo0mh+s6nv1bPull2YYlffqe0jmd4+TaY4cso2luHpoov\n# MIIFMTCCBBmgAwIBAgIQCqEl1tYyG35B5AXaNpfCFTANBgkqhkiG9w0BAQsFADBl\n# MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n# d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv\n# b3QgQ0EwHhcNMTYwMTA3MTIwMDAwWhcNMzEwMTA3MTIwMDAwWjByMQswCQYDVQQG\n# EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl\n# cnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0\n# YW1waW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdAy7kvN\n# j3/dqbqCmcU5VChXtiNKxA4HRTNREH3Q+X1NaH7ntqD0jbOI5Je/YyGQmL8TvFfT\n# w+F+CNZqFAA49y4eO+7MpvYyWf5fZT/gm+vjRkcGGlV+Cyd+wKL1oODeIj8O/36V\n# +/OjuiI+GKwR5PCZA207hXwJ0+5dyJoLVOOoCXFr4M8iEA91z3FyTgqt30A6XLdR\n# 4aF5FMZNJCMwXbzsPGBqrC8HzP3w6kfZiFBe/WZuVmEnKYmEUeaC50ZQ/ZQqLKfk\n# dT66mA+Ef58xFNat1fJky3seBdCEGXIX8RcG7z3N1k3vBkL9olMqT4UdxB08r8/a\n# rBD13ays6Vb/kwIDAQABo4IBzjCCAcowHQYDVR0OBBYEFPS24SAd/imu0uRhpbKi\n# JbLIFzVuMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMBIGA1UdEwEB\n# /wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMI\n# MHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl\n# cnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v\n# RGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRo\n# dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0Eu\n# Y3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1\n# cmVkSURSb290Q0EuY3JsMFAGA1UdIARJMEcwOAYKYIZIAYb9bAACBDAqMCgGCCsG\n# AQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAsGCWCGSAGG/WwH\n# ATANBgkqhkiG9w0BAQsFAAOCAQEAcZUS6VGHVmnN793afKpjerN4zwY3QITvS4S/\n# ys8DAv3Fp8MOIEIsr3fzKx8MIVoqtwU0HWqumfgnoma/Capg33akOpMP+LLR2HwZ\n# YuhegiUexLoceywh4tZbLBQ1QwRostt1AuByx5jWPGTlH0gQGF+JOGFNYkYkh2OM\n# kVIsrymJ5Xgf1gsUpYDXEkdws3XVk4WTfraSZ/tTYYmo9WuWwPRYaQ18yAGxuSh1\n# t5ljhSKMYcp5lH5Z/IwP42+1ASa2bKXuh1Eh5Fhgm7oMLSttosR+u8QlK0cCCHxJ\n# rhO24XxCQijGGFbPQTS2Zl22dHv1VjMiLyI2skuiSpXY9aaOUjGCBAMwggP/AgEB\n# MC4wGjEYMBYGA1UEAwwPWmlwQXV0aGVudGljb2RlAhAc7dlWYyBKgErqSIVG8WQf\n# MAkGBSsOAwIaBQCgeDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3\n# DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEV\n# MCMGCSqGSIb3DQEJBDEWBBQd12oYFtYD2RrO2YbEOurpoGz8KjANBgkqhkiG9w0B\n# AQEFAASCAQCUevV4BNm6XpeNBdDi84OyQP/qz4guQJfeEoTfwLbrvNtu7wqghCtM\n# UlXyN9+3AJBuyPgzmXWXX2cuSme1AOQZLuvf8x405/37h5B7lhUHN+pCwcSjLB+T\n# IfDq6m6P6uynRltbDzUTRBAboCnZwzvpcFaLtX1ve/sCB8HeDx6rRobw37nhGr5y\n# LR89tG/gcGrQ/gAwe8DitRQ/e2f+lMEn/LUMlzzt7Tx09zBcTNkcMHZXGrwFHwJE\n# e9UBHTUMGOCAslAFIqOT1WznRYMpHmuvLhC6zF4xTCC8nNcF6LxVIW9a57MbJKRJ\n# UJr+Ugxnf7Dg/rP2ccX/Wxc72qy4lOj6oYICMDCCAiwGCSqGSIb3DQEJBjGCAh0w\n# ggIZAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx\n# GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNI\n# QTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0ECEA1CSuC+Ooj/YEAhzhQA8N0w\n# DQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqG\n# SIb3DQEJBTEPFw0yMjAzMTUxNzI1MDNaMC8GCSqGSIb3DQEJBDEiBCCpGJlS66sl\n# ngoou7SKFpsLJTTcWPEJmzWTiEz1M1GRvjANBgkqhkiG9w0BAQEFAASCAQA07rIo\n# adJh+rrIMXwy3D3RspJupxlCoGImxzXQGwBNcN1uPoUjwmnBi++i3dZnMafLdetC\n# WfxCOOy8+xRvEy0ossv4rvU//xDe0O0LCrFK6tjuhhuZezKvz8YI+eOB9LrDFv1l\n# G9l7h7Eh3HdeCiBOkG1OreAtcXeDb2fdg+t3URfEacAoJKdTC9w69wFU2c/h6DeZ\n# fB8nVjlJk/WdwEZp2FYi3huEv+s4ZiMC7iGzlilL3eRtQwpSmlSNPVh5p3QeUxmz\n# XR+TwLYu43RZTovFPnZ8i/8q9N4J3QmWDw4xknpiDBPqWJOQ+VI+nqLKwaCphOk7\n# hzTR1bUjsM+zHDA1\n# SIG # End signature block\n```\n\nSince Authenticode doesn't support the zip file format natively, we use a file hash of the zip file as if it had no comment appended at the end of it. We convert this hash to the [OCI digest string](https://github.com/opencontainers/image-spec/blob/v1.0.1/descriptor.md#digests) string format and create a one-line .sig.ps1 file with it. This file is then signed like a PowerShell script, except it doesn't contain executable code. The digest string and the signature block are then reformatted to be embedded as a single-line comment inside the zip file format, like this:\n\n```\nZipAuthenticode=sha256:4667433dd582f5955e7f6355cbb2a39c5e95cbccc894c1ffaa4286f1acfed0b7,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\n```\n\nTo validate the signature, we extract lines beginning with \"ZipAuthenticode\" from the zip file comment field, and reconstruct original script formatting. We then compute the zip file digest excluding the comment field itself, compare it with the digest embedded in the signature, and validate the signature file as a PowerShell script. If the digest strings match and the signature on the script is valid, then the zip file is correctly signed.\n\n## Validating using signtool\n\nExtract the signature script file from the zip file:\n\n```powershell\nExport-ZipAuthenticodeSignature .\\test.zip\n```\n\nValidate the signature script file using signtool:\n\n```powershell\nsigntool verify /pa /v test.zip.sig.ps1\n\nVerifying: .\\test.zip.sig.ps1\n\nSignature Index: 0 (Primary Signature)\nHash of file (sha1): 45B60E63B237F3265E0682B1D240B722AA7DBD1E\n\nSigning Certificate Chain:\n    Issued to: ZipAuthenticode\n    Issued by: ZipAuthenticode\n    Expires:   Sun Mar 12 16:30:04 2023\n    SHA1 hash: 6256DFDA7528DF20730950A4D9DC0727CE7EA404\n\nThe signature is timestamped: Tue Mar 15 13:25:03 2022\nTimestamp Verified by:\n    Issued to: DigiCert Assured ID Root CA\n    Issued by: DigiCert Assured ID Root CA\n    Expires:   Sun Nov 09 20:00:00 2031\n    SHA1 hash: 0563B8630D62D75ABBC8AB1E4BDFB5A899B24D43\n\n        Issued to: DigiCert SHA2 Assured ID Timestamping CA\n        Issued by: DigiCert Assured ID Root CA\n        Expires:   Tue Jan 07 08:00:00 2031\n        SHA1 hash: 3BA63A6E4841355772DEBEF9CDCF4D5AF353A297\n\n            Issued to: DigiCert Timestamp 2021\n            Issued by: DigiCert SHA2 Assured ID Timestamping CA\n            Expires:   Sun Jan 05 20:00:00 2031\n            SHA1 hash: E1D782A8E191BEEF6BCA1691B5AAB494A6249BF3\n\n\nSuccessfully verified: .\\test.zip.sig.ps1\n\nNumber of files successfully Verified: 1\nNumber of warnings: 0\nNumber of errors: 0\n```\n\nExtract the zip digest string from the signature file:\n\n```powershell\n(Get-Content .\\test.zip.sig.ps1)[0]\nsha256:4667433dd582f5955e7f6355cbb2a39c5e95cbccc894c1ffaa4286f1acfed0b7\n```\n\nCompute the zip digest hash on the zip file, and then compare the value:\n\n```powershell\n(Get-ZipAuthenticodeFileHash .\\test.zip).ToDigestString()\nsha256:4667433dd582f5955e7f6355cbb2a39c5e95cbccc894c1ffaa4286f1acfed0b7\n```\n\n## Signing using signtool\n\nExport the zip file digest string to a .sig.ps1 text file (UTF-8 encoding, no BOM, and no line ending characters):\n\n```powershell\nGet-ZipAuthenticodeDigest .\\test.zip -Export\n\nDigest                                                                  Path\n------                                                                  ----\nsha256:4667433dd582f5955e7f6355cbb2a39c5e95cbccc894c1ffaa4286f1acfed0b7 test.zip\n```\n\nSign test.zip.sig.ps1 using signtool as if it were a PowerShell script:\n\n```powershell\n$cert = @(Get-ChildItem cert:\\CurrentUser\\My -CodeSigning | Where-Object { $_.Subject -eq \"CN=ZipAuthenticode\" })[0]\nsigntool sign /fd SHA256 /t 'http://timestamp.digicert.com' /sha1 $cert.Thumbprint /v test.zip.sig.ps1\n\nThe following certificate was selected:\n    Issued to: ZipAuthenticode\n    Issued by: ZipAuthenticode\n    Expires:   Sun Mar 12 16:30:04 2023\n    SHA1 hash: 6256DFDA7528DF20730950A4D9DC0727CE7EA404\n\nDone Adding Additional Store\nSuccessfully signed: test.zip.sig.ps1\n\nNumber of files successfully Signed: 1\nNumber of warnings: 0\nNumber of errors: 0\n```\n\nImport the signature from the .sig.ps1 file into the zip file:\n\n```powershell\nImport-ZipAuthenticodeSignature .\\test.zip -Remove\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevolutions%2Fdevolutions-authenticode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevolutions%2Fdevolutions-authenticode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevolutions%2Fdevolutions-authenticode/lists"}