8
votes

I am trying to build a click-once application using the Continuous integration and deployment feature in VSTS (Visual studio team services Online)We are trying to build this using the Hosted agent Visual studio 2015 We had difficulties signing the strong name key file with an error of

MSB3326: Cannot import the following key file: xxxx.snk. The key file may be password protected. To correct this, try to import the certificate again or import the certificate manually into the current user's personal certificate store. And after that

MSB3321: Importing key file "xxxx.pfx" was canceled.

I have tried to both select from store and from file changed the location and made sure to commit but with no success. Any ideas how i can overcome this errors or what am doing wrong.

Clerification on answer selected

Just wanted to make a clarification if anyone else has the same issue, in addition to the answer i had to place my certificate in my source control code and commit it. Then to select its location add a global variable on the VSTS Build

enter image description here

$cert.Import("$(CertPath)", $password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet") Where $(CertPath) would be something like $(Build.SourcesDirectory)\SharedSolutionFiles\CertificateName.pfx

3
(almost) same exact question as stackoverflow.com/questions/11155858/… but but this issue cannot be solved by the answers on that question as OP is in the cloud. Be forewarned, folks who might dupehammeruser1228

3 Answers

13
votes

You can create a PowerShell script and add a PowerShell Script step in your build definition to import the certificate file before the VSBuild step.

Build failed without PowerShell Import Certificate Step: enter image description here

Build passed with PowerShell Import Certificate Step: enter image description here

The PowerShell Script I used:

$pfxpath = 'pathtoees.pfx'
$password = 'password'

Add-Type -AssemblyName System.Security
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($pfxpath, $password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet")
$store = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "MY", CurrentUser
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite")
$store.Add($cert)
$store.Close()
1
votes

The better way is that you can setup a on premise build agent and import the certificate to certificate store, then change build agent service account to the same account.

0
votes

Instead of using either an on premise build or loading the certificates on to the certificate stores on the build agent (which could be considered insecure) it is possible to overwrite the build task FileSign and construct one that uses a certificate file and password.

I have outlined the steps here: https://stackoverflow.com/a/55313239/2068626