14

I try to create a self-signed code signing certificate via powershell to sign a .NET assembly through Visual Studio 2017 with it as a pfx afterwards. The pfx is exported as a domain-protected certificate using -ProtectTo argument. The code is as follows:

$pfxLocation = [System.IO.Path]::Combine([System.Environment]::GetFolderPath("Desktop"),"Certificates\")
New-Item -ItemType Directory -Path $pfxLocation -Force
$certificate = New-SelfSignedCertificate `
               -CertStoreLocation "Cert:\LocalMachine" `
               -FriendlyName "This is a code-signing certificate" `
               -Subject "CN=Me" `
               -Type CodeSigningCert `
               -NotBefore ([System.DateTime]::Today) `
               -NotAfter ([System.DateTime]::Today.AddMonths(6).AddDays(1)) `
               -KeyExportPolicy Exportable
Move-Item -Destination "Cert:\LocalMachine\Root" -Path $certificate.PSPath
$newCertificateLocation = "Cert:\LocalMachine\Root\" + $certificate.Thumbprint
Get-ChildItem $newCertificateLocation | Export-PfxCertificate -FilePath ([System.IO.Path]::Combine($pfxLocation,"certificate.pfx")) -ProtectTo "Domain\Domain group 1", "Domain\Domain group 2"

However, Visual Studio still demands a non-existent password.

VS2017 password request

Password from domain user from one of domain groups specified with -ProtectTo argument is rejected:

VS2017 rejects password

So what password does it request and why does it require any at all? As it's domain-protected, it shouldn't have any, and that's exactly what I was aiming at.

UPDATE

Basically, the idea is to use output pfx for code signing with automated build agents, for which absence of password is kind of a must.

  • 1
    There are several requirements that must be in place for this feature to work: 1) The digital certificate must be exported from a Windows 8 or higher or Windows Server 2012 or higher domain member. 2) The certificate client must be joined to a domain with a Windows Server 2012 domain controller available. 3) The digital certificate must be exported in the PKCS#12 (PFX) file format – user1367200 Jul 27 '18 at 01:02
  • Some more details about this feature here: https://social.technet.microsoft.com/wiki/contents/articles/13922.certificate-pfx-export-and-import-using-ad-ds-account-protection.aspx – user1367200 Jul 27 '18 at 01:03
  • 1
    Also, based on what I'm reading: There is actually a password created on the exported PFX file, even when the file is secured to an AD DS account. This allows client computers prior to Windows 8 and Windows Server 2012 to access the file. – user1367200 Jul 27 '18 at 01:06
  • 1
    @user1367200 Thanks for your attention. All of the requirements you've mentioned in your first comment is satisfied. As for the second comment, WELL, THAT'S RICH, since there is no way to actually KNOW this password, is there? Basically, the idea is to use this certificate for code signing via automated builds with little to none human interaction, and this kinda defeats the whole purpose. – Aleksei Omelaienko Jul 28 '18 at 20:15
  • "-ProtectTo specifies an array of strings for the username or group name that can access the private key of PFX file without any password. This requires a Windows Server® 2012 domain controller. Either the Password or this parameter must be specified, or an error will be displayed." Seems though that it SHOULDN'T require a password from users and groups identified. – Aleksei Omelaienko Jul 28 '18 at 20:20
  • Can you explain a bit more how you are getting the error message in Visual Studio? The code for creating the certificate in PowerShell appears correct, and indeed creates a certificate without any "password" prompt (assuming you are running it as one of the allowed users and are running it as administrator (in order to import the cert into the store)). It looks like the importing of the certificate into ?x? that's what Visual Studio is prompting to open the certificate. – HAL9256 Aug 01 '18 at 22:46
  • To verify that the `-ProtectTo` works, take your `certificate.pfx` file that you created, and try to import it. go through the wizard, and you will get to the Private Key Protection screen with the password filled in with asterisks. There is a checkbox that says Display password, which would display the "hidden" password. – HAL9256 Aug 01 '18 at 22:53
  • Not sure if this is impacted by the functional level of your domain controller, or if it's solely the OS... What do you get if you run `(Get-ADForest).ForestMode; (Get-ADDomain).DomainMode`? (requires the `ActiveDirectory` module). – JohnLBevan Aug 22 '18 at 23:52
  • @AlekseiOmelaienko Do you still need a hand with this? Could you make an update stating the requirements clearly? I might have something to add... – Mötz Dec 22 '18 at 10:14
  • @Mötz I actually do, thank you. Though I can't think how to state the requirements any clearer than this — I need a code signing certificate to be used by automated build agent, thus one not requiring password input. – Aleksei Omelaienko Dec 23 '18 at 11:07

2 Answers2

1

This export PFX without password. When importing this through GUI, you can use empty password.

$cert = @(Get-ChildItem -Path 'Cert:\CurrentUser\My\07BAE0886EECC2019F0AE6CC68FE5C3EA98308F8')[0]
$certBytes = $cert.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx)
[System.IO.File]::WriteAllBytes('S:\cert.pfx', $certBytes)
filimonic
  • 3,988
  • 2
  • 19
  • 26
0

Does this work for you?

& certutil -v -privatekey certificate.pfx | ? {$_ -match "^PFX protected password: ""(?<password>.*)""$"} | % { $matches.password }
spongyryno
  • 446
  • 2
  • 12