{"id":3461,"date":"2022-06-24T16:40:21","date_gmt":"2022-06-24T20:40:21","guid":{"rendered":"https:\/\/www.tmurgent.com\/TmBlog\/?p=3461"},"modified":"2022-06-24T16:40:21","modified_gmt":"2022-06-24T20:40:21","slug":"a-self-signed-code-signing-certificate-for-msix-wap","status":"publish","type":"post","link":"https:\/\/www.tmurgent.com\/TmBlog\/?p=3461","title":{"rendered":"A self-signed Code Signing Certificate for MSIX WAP"},"content":{"rendered":"\n<p>Developers creating MSIX packages with the Windows Application Project (WAP) need to provide a code-signing certificate with an additional field not needed when creating packages through other means.\u00a0 Specifically, it needs the BasicConstraints field in the certificate.<\/p>\n<p>If you purchase a code signing certificate from a Certificate Authority, this field should already be there.\u00a0 But in this case I was working on behalf of a customer and they shouldn&#8217;t be giving my their production code-signing certificate.\u00a0 Instead, I usually create a self-signed certificate with the same &#8220;subject&#8221; field as their production cert.\u00a0 Then I can create the package and test using this test cert and they only need to re-sign the package with their production cert when I&#8217;m done.<\/p>\n<p>But importing the test cert into WAP AppxManifest file in Visual Studio using a test cert make the same way as I&#8217;d always creating them with other tooling wouldn&#8217;t import the cert into the project.\u00a0 Specifically, the error looked like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-3462\" src=\"https:\/\/www.tmurgent.com\/TmBlog\/wp-content\/uploads\/2022\/06\/Cert-Import.png\" alt=\"\" width=\"702\" height=\"482\" srcset=\"https:\/\/www.tmurgent.com\/TmBlog\/wp-content\/uploads\/2022\/06\/Cert-Import.png 702w, https:\/\/www.tmurgent.com\/TmBlog\/wp-content\/uploads\/2022\/06\/Cert-Import-300x206.png 300w\" sizes=\"auto, (max-width: 702px) 100vw, 702px\" \/><\/p>\n<p>Looking at the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=241478\" target=\"_blank\" rel=\"noopener\">Microsoft Documentation<\/a> it mentions the need for the &#8220;BasicConstraints&#8221; field to be in the cert, but simply states<\/p>\n<pre><span style=\"background-color: #ffffff;\">\"The value of the\u00a0<strong>Basic Constraints<\/strong>\u00a0extension is set to\u00a0<strong>Subject Type=End Entity\"<\/strong> <\/span><\/pre>\n<p>with no information on how to make that happen other than asking Visual Studio to make a test cert for you.\u00a0 But then you can&#8217;t control the subject field as it only makes the subject field by slapping CN= in front of the Company Name (which won&#8217;t match any cert from a public Certificate Authority).\u00a0<\/p>\n<p>As I have a script to create the test cert using PowerShell New-CodeSigningCert cmdlet you&#8217;d think you might find something in documentation or forums there.\u00a0 But all I found were uses for adding BasicConstraints for purposes other than a code signing cert which did not help.\u00a0 Eventually I found <a href=\"https:\/\/www.encryptionconsulting.com\/introduction-to-certificate-extension-basic-constraints\/\">Introduction to Certificate Extensions | Basic Constraints (encryptionconsulting.com)<\/a> which provided me the correct syntax for my purpose.<\/p>\n<p>Below is a PowerShell script I use to generate an acceptable code signing certificate.\u00a0 It will prompt you for the necessary information, create the cert, and export the pfx file for you with a password.\u00a0 It must be run in an elevated PowerShell window.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent\r\n\r\r\n\r\nWrite-Host \r\nWrite-Host -ForegroundColor Cyan 'Input information for your certificate below:'\r\n$Company_Entered = Read-Host -Prompt \"Enter your company name (Default='Company')\" \r\n$CN = Read-Host -Prompt \"Enter Subject aka CN=... (Default=leave blank to  create from company name)\"\r\n$Password_Entered = Read-Host -Prompt \"Enter a password (Default='3.14159')\"\r\nif ($Company_Entered.Length -lt 3) \r\n{ \r\n    $Company_Entered = 'Company'\r\n    Write-Host \"Company name defaulted to '$($Company)\"\r\n}\r\nif ($CN.Length -gt 0)\r\n{\r\n    $Publisher_CN = $CN\r\n}\r\nelse\r\n{\r\n    $Publisher_CN=\"CN=$($Company_Entered)\"\r\n}\r\nWrite-Host \"Subject is $($Publisher_CN)\"\r\nif ($Password_Entered.Length -lt 3)\r\n{ \r\n    $Password_Entered = '3.14159'\r\n    Write-Host \"Password defaulted to '$($Password_Entered)\"\r\n}\r\n\r\nWrite-Host -ForegroundColor Cyan 'Processing...'\r\n$Publisher_DisplayName = \"$($Company_Entered)\"\r\n$Password=$Password_Entered\r\n$FolderToExportCert = \"$($executingScriptDirectory)\"\r\n$CertName=\"$($Company_Entered)\"\r\n$pwd=ConvertTo-SecureString -String $Password -Force -AsPlainText\r\n$pfxName = \"$($FolderToExportCert)\\$($CertName).pfx\"\r\n\r\n$cert = New-SelfSignedCertificate -Subject $Publisher_CN -FriendlyName $Publisher_DisplayName -KeyAlgorithm RSA -KeyLength 3072 -Provider \"Microsoft Enhanced RSA and AES Cryptographic Provider\" -KeyExportPolicy Exportable -KeyUsage DigitalSignature -Type CodeSigningCert -CertStoreLocation \"Cert:\\LocalMachine\\my\" -KeyDescription \"Code Signing Cert for MSIX Packages\" -NotAfter \"12\/31\/2039 23:59:59\" -HashAlgorithm 'SHA256' -TextExtension @(\"2.5.29.19={text}CA=false\")\r\n$cert | Export-PfxCertificate -FilePath $pfxName -Password $pwd -Force -CryptoAlgorithmOption AES256_SHA256\r\n\r\nWrite-Host -ForegroundColor Cyan \"Exported Certificate: File: $($pfxName)\"\r\nWrite-Host -ForegroundColor Cyan \"        MSIX Manifest uses: $($Publisher_CN)\"\r\nWrite-Host -ForegroundColor Cyan \"               Valid until: $($cert.NotAfter)\"\r\n\r\n\r\nRemove-Item $cert.PSPath\r\nWrite-Host -ForegroundColor Cyan \"Done.\"\r\npause<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Developers creating MSIX packages with the Windows Application Project (WAP) need to provide a code-signing certificate with an additional field not needed when creating packages through other means.\u00a0 Specifically, it needs the BasicConstraints field in the certificate. If you purchase a code signing certificate from a Certificate Authority, this field should already be there.\u00a0 But&hellip; <a class=\"more-link\" href=\"https:\/\/www.tmurgent.com\/TmBlog\/?p=3461\">Continue reading <span class=\"screen-reader-text\">A self-signed Code Signing Certificate for MSIX WAP<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3462,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[53],"tags":[52],"class_list":["post-3461","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-msix","tag-msix","entry"],"_links":{"self":[{"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=\/wp\/v2\/posts\/3461","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3461"}],"version-history":[{"count":1,"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=\/wp\/v2\/posts\/3461\/revisions"}],"predecessor-version":[{"id":3463,"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=\/wp\/v2\/posts\/3461\/revisions\/3463"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=\/wp\/v2\/media\/3462"}],"wp:attachment":[{"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3461"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3461"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tmurgent.com\/TmBlog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3461"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}