How to extend the expiry date of windows app certificate? We're side loading the app/ The main obstacle is the certificate expires every year which is a bothersome to renew it through GP cause we already have issues in our environment. We would like to extend it for at least 5 years.
I have managed to find technet articles on how to create a code signing certificate but it didnt work. Visual studio doesnt accept the certificate and gives an error message that it is corrupted or invalid.
https://learn.microsoft.com/en-us/windows/uwp/packaging/create-certificate-package-signing#create-a-self-signed-certificate
https://technet.microsoft.com/itpro/powershell/windows/pki/new-selfsignedcertificate
Is there any way to do it easily?
You could do something like this, the subject must be same as UWP app's Publisher (package.appxmanifest):
New-SelfSignedCertificate -Type Custom -Subject "CN=Something" -TextExtension #("2.5.29.37={critical}{text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") -KeyUsage DigitalSignature -FriendlyName "Friendly Name" -CertStoreLocation "Cert:\LocalMachine\My" -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(5)
Now export to .pfx and add the thumbprint to the PackageCertificateThumbprint
The process is described in Microsoft documentation, but it is convoluted. There is no "visual" part as "Visual Studio" would suggest.
To sideload an application, it is sufficient to create a self-signed certificate, which means that you trust yourself. There is no trust from a CA (certification authority) involved.
These steps worked for me. The whole process being in PowerShell run as administrator.
Create the certificate
New-SelfSignedCertificate -Type Custom -Subject "CN=Company Name, O=Company Name Inc., C=CA" -KeyUsage DigitalSignature -FriendlyName "Programming certificate, 50 years" -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension #("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(50)
The -Subject item may contain only the CN= part, I believe the other bits are optional. O= seems to refer to the organization and C= the country code.
The -CertStoreLocation and -TextExtension are correct as written (see the documentation). I am not too familiar with what -CertStoreLocation really means, as I was not able to find it later, but that is what Microsoft suggests and remains irrelevant to the process.
The (Get-Date) bits get the current date, and .AddYears(50) would be modified to how many years the certificate should last.
The output will display the thumbprint; copy it.
Export the certificate
Set a password variable (confusingly, the password here is written without quotes).
$password = ConvertTo-SecureString -String CustomPasswordYouWouldChoose -Force -AsPlainText
Export the certificate; paste the thumbprint in the "Cert:\CurrentUser\My..." string and choose a file path (in my case, using the C:\ drive worked fine).
Export-PfxCertificate -cert "Cert:\CurrentUser\My\YOURTHUMBPRINTHERE" -FilePath C:\ProgrammingCertificate.pfx -Password $password
Add the certificate in Visual Studio
Go to Package.appxmanifest > Packaging > Choose Certificate... > Select from file... > then select your exported certificate.
Install the certificate on sideload deployment
Double-click the certificate file > Install Certificate... > Local Machine > Place all certificates in the following store > Browse > Trusted People > accept all and the import should be successful. Congratulations, the application is now certified by yourself.
Related
I have a VSTO add-in which I'm migrating from VS2010 to visual studio 2019. However, I forgot the password to mypfx key attached to the main project of the solution.
I'm now trying to create a new one and import it into my project to replace the old key which I can't use anymore. I've tried subsequent steps indicated on stackoverflow and other sites, but I keep getting the following build error in VS2019:
Cannot import the following key file: newtest.pfx. The key file may be password protected.
To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: VS_KEY_10580C0D68F0E891 <project name>
However, that's exactly what I'm trying. First, I create a new certificate as indicated here:
New-SelfSignedCertificate -DnsName "somename" -CertStoreLocation "cert:\LocalMachine\My"
Then I export it :
$CertPassword = ConvertTo-SecureString -String “somepass” -Force –AsPlainText
Export-PfxCertificate -Cert cert:\LocalMachine\My\<somethumbprint> -FilePath <path>/newtest.pfx -Password $CertPassword
Final step, as in this question is to use sn.exe with the following command:
sn -i sg newtest.pfx VS_KEY_XXXXXXXXXXXX
The command runs successfully, but when I restart vs2019 again and open the add-in solution, the samen error pops up again. What can I do?
EDIT
Also, I cannot uncheck the "sign clickonce manifest" checkbox in Project > Properties > Signing. THis means that the Select from store option as mentioned in the answer below is unavailable.
I have moved this project to another computer, could that be the cause?
A bit stuck here.
I had the exact same problem a few weeks ago. What helped in my case is that I created the certificate just like you (placed in the Personal Certificate Store), then instead of the command line tools I used the Signing menu in Visual Studio 2019 to import the cert.
Right Click on the Project, then Properties, then Signing. Enable Sign the ClickOnce manifest and Select from Store to use the newly created certificate.
I am trying to import a certificate into my "Local computer" account under "Personal" certificate store.
Though when running one of the below 2 commands, the certificate is imported into a new certificate store called also Personal.
First command:
Import-Certificate -FilePath "C:\Users\myUser\Desktop\LabCert.cer" -CertStoreLocation 'Cert:\LocalMachine\Personal' -Verbose
Second command:
CertUtil -v -addstore "Personal" "C:\Users\myUser\Desktop\LabCert.cer"
Can someone please advise how can I import my certificate into the original Personal store?
Thanks
I'm setting up a new development laptop, and have installed a self-issued code signing certificate. I can see it in certmgr under my Current Users's Personal Certificates.
When I try to build from the Developer Command Prompt For Visual Studio 2017 I get:
error : SignTool Error: No certificates were found that met all the given criteria.
This always worked fine on my old laptop.
I have found if I run the same build from the command prompt after starting it as admin that signtool succeeds and can find the cert.
This has happened to 3/4 colleagues when we've set up new laptops. One guy is ok and can sign without running as admin. On our old laptops we never had to run as admin.
I've tried googling to find what could be the cause because I wasn't aware that running as admin or not should have any affect over this. I haven't found any reference to this problem.
How can we use signtool.exe without running it as admin?
When not running as admin it appears to be at the Private Key filter step where the cert I'm expecting to be selected gets filtered out:
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.12
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
C:\>signtool sign /v /debug /ph /i "<issuedby>" /fd sha256 /td sha256 "C:\TestSign.dll"
The following certificates were considered:
Issued to: Scott Langham
Issued by: <issuedby>
Expires: Sun Sep 25 09:54:55 2022
SHA1 hash: <a_hash>
Issued to: Scott Langham
Issued by: <issuedby_somethingelse>
Expires: Wed May 13 15:51:14 2020
SHA1 hash: <b_hash>
After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
After Issuer Name filter, 1 certs were left.
After Private Key filter, 0 certs were left.
SignTool Error: No certificates were found that met all the given criteria.
I've ensured the version of signtool.exe I'm using is the same as the one that my colleague who has this working is using (10.0.18362.1). I've been able to spot any other differences between our systems.
I ran into this today and here is how I am now able to run signtool.exe via command line without elevating to admin.
Run 'mmc' and add the 'Certificates' snap-in
Select the correct key store location
(mine is in Local Computer so I select 'Computer account' here)
Find and select the certificate
Right click on the certificate, select All Tasks > Manage Private Keys...
In the 'Permissions for private keys' dialog, Add your user account and then give yourself 'Full Control'. You will now be able to sign using a normal command prompt.
Note: If you use a build machine, do the above steps for the account that performs the builds.
Similar to what #Baget said, I'd compare the certificates on your machine to that of your colleague who can successfully run the SignTool.exe command without the elevation token. Here's a chunk of PowerShell to assist you:
get-childitem -Path Cert:\ | foreach-object ({
$location = $_.Location
foreach($store in $_.StoreNames.Keys) {
get-childitem -Path "Cert:\$location\$store" | foreach-object ({
$thumb = $($_.ThumbPrint)
$issuer = $($_.Issuer)
if ($issuer -eq "CN=EXAMPLE, DC=EXAMPLE, DC=EXAMPLE, DC=EXAMPLE") {
write-host "$location $store $issuer"
}
})
}
})
Bear in mind that the output of the above may differ slightly if you run as a normal user and 'run as admin'.
Finally, do you and your colleague have the same UAC settings?
I found myself in a similar situation with signtool, it refused to work with an admin user but does work as actual Administrator.
In my case, I am not actually importing the certificate into the certificate store, but using a .pkcs12 file exported from a comodo certificate in firefox, so this makes things even stranger, as no permissions on any keys in the store are involved.
I tried granting myself permissions on some server key, but that did nothing.
I hope someone finds a solution to this problem.
In the meantime, I am signing my exe with osslsigncode instead, which works perfectly.
I extracted the exe and dependent dlls from the msys2 mingw64 build, here is a zip of everything in case it is of use to anyone, just extract it to a directory and put it in your PATH.
http://cachemiss.com/files/osslsigncode.zip
To extract this program yourself from an msys2 installation, you can use this command:
pacman --noconfirm -S mingw-w64-x86_64-osslsigncode
cd /mingw64/bin
mkdir ~/osslsigncode
cp osslsigncode.exe $(ldd osslsigncode.exe | sed -n 's,^.*\(/mingw64/[^ ]*\).*,\1,p' | sort -u) ~/osslsigncode/
cd
zip -9r osslsigncode.zip osslsigncode
I am using this in Visual Studio cmake builds with no issue.
There are two Certificate Store in Windows, User Store, and a machine store, you probably installed the certificate to the local machine, or you installed it when you run as elevated user.
Firstly you are getting such an error and you are using visual studio then See the signing tab in project properties. You will see a previously assigned signature (strong assembly)
If you enter the correct password here:
If your environment is the same as the environment in which the project is written, you will skip this error. Look the post on about the error
The reasons behind this error are:
1- Visual Studio needs some features when using certificate file to sign strong assembly.
ClickOnce Manifest Signing and Strong-Name Assembly Signing Using Visual Studio Project Designer's Signing Page
You can try this code to determine
signtool sign /debug /f mypfxfile.pfx /p <password> (mydllexectuable).exe
2- These settings can vary from machine to machine, and windows does not write these settings to the environment setting by default. check the config path
This part is just a deep note! not interested with the question you should add your private keystore file to request header and those all for this. My favorite steps about the creation of a certificate on this post
When using powershell to investigate the Certificate Provider i noticed that all the paths seem similar but not the same as the folder structure within certmgr. It seems pretty clear that:
Certs:\LocalMachine ~= Certificates (Local Computer)
Certs:\CurrentUser ~= Certificates - Current User
I'm also guessing that:
Root ~= Trusted Root Certification Authority
My ~= Personal
WebHosting ~= WebHosting
...
But i have been unable to find any sort of official reference (or even sensible explanation) to give me the warm fuzzy I'm looking for...
My intent is to test an https WCF service locally (both server and client side). I can easily generate the self signed certificate needed by the server using New-SelfSignedCertificate. However, if I try to point my client (also .NET) at the service it fails to connect given that the service serves up a non-trusted certificate.
I have found various out-dated references (like this one), showing how I could use a combination of makecert (now deprecated), and certmgr to generate a certificate authority, then use it to sign the cert for my https service, then install the certificate authority cert into Trusted Root Certification Authority container to get everything working. While this approach would likely work, it is certainly not developer/automation friendly.
That said, I was able to use powershell to do this:
$my_cert_store_location = "Cert:\LocalMachine\My"
$root_cert_store_location = "Cert:\LocalMachine\Root"
$root_friendly_name = "Test Root Authority"
$root_cert_subject = "CN=$($root_friendly_name)"
# The ip and port you want to reserve for your app
$ipport = "127.0.0.11:8734"
# Your app guid (found in ApplicationInfo.cs)
$appid = "{f77c65bd-d592-4a7b-ae32-cab24130fdf6}"
# Your dns name
$dns_name = "my-machine-local"
$rebuild_root_cert = $false
$root_cert = Get-ChildItem $my_cert_store_location |
Where-Object {$_.SubjectName.Name.Equals($root_cert_subject)}
if ($root_cert -and $rebuild_root_cert)
{
Get-ChildItem $root_cert_store_location |
Where-Object {$_.SubjectName.Name.Equals($root_cert_subject)} |
Remove-Item
Remove-Item $root_cert
$root_cert = $false
}
if (-not $root_cert)
{
$root_cert = New-SelfSignedCertificate `
-Type Custom `
-FriendlyName $root_friendly_name `
-HashAlgorithm sha384 `
-KeyAlgorithm RSA `
-KeyLength 4096 `
-Subject $root_cert_subject `
-KeyUsage DigitalSignature, CertSign `
-NotAfter (Get-Date).AddYears(20) `
-CertStoreLocation $my_cert_store_location
Write-Output "Created root cert: $($root_cert.Thumbprint)"
$exported_cert = New-TemporaryFile
Export-Certificate -Cert $root_cert -FilePath $exported_cert.FullName
$imported_root_cert = Import-Certificate -FilePath $exported_cert.FullName `
-CertStoreLocation $root_cert_store_location
Write-Output "Imported root cert to: $($root_cert_store_location)\$($imported_root_cert.Thumbprint)"
}
Write-Output "Root cert is: $($root_cert.Thumbprint)"
$test_signed_cert_subject = "CN=$($dns_name)"
$test_signed_cert = Get-ChildItem $my_cert_store_location |
Where-Object {$_.SubjectName.Name.Equals($test_signed_cert_subject)}
if (-not $test_signed_cert)
{
$test_signed_cert = New-SelfSignedCertificate `
-Type Custom `
-Subject $test_signed_cert_subject `
-FriendlyName $dns_name `
-Signer $root_cert `
-CertStoreLocation $my_cert_store_location
Write-Output "Created signed cert: $($test_signed_cert.Thumbprint)"
}
Write-Output "Signed cert is: $($test_signed_cert.Thumbprint)"
if ($test_signed_cert)
{
netsh http delete sslcert `
ipport="$($ipport)"
netsh http add sslcert `
ipport="$($ipport)" `
appid="$($appid)" `
certstorename="My" `
certhash="$($test_signed_cert.Thumbprint)"
Write-Output "Assigned signed cert to: $($ipport)"
}
But the question still stands... Is there any information about how the certificate provider paths map to certmgr folders?
Here is the mapping between containers (in parentheses) and their description:
Personal (My) — This container is used to store certificates with private keys. When a certificate private key is used, the application looks to this container to find the appropriate certificate and associated private key.
Trusted Root Certification Authorities (ROOT) — This container contains trusted, self-signed certificates without private keys. Each certificate chain must chain up to a certificate presented in self-signed form. This self-signed certificate is the ‘root certificate’ or ‘trusted anchor.’ However, not all root certificates can be considered as trusted. You should carefully choose which new certificates you will consider as trusted.
Enterprise Trust (trust) — This container is used to store Certificate Trust Lists (CTL). For example, the Key Management Server adds its certificate to this container.
Intermediate Certification Authorities (CA) — This container keeps many different types of CA certificates. These certificates are usually used by the certificate chaining engine to build certificate chains.
Trusted Publishers (TrustedPublisher) — This container keeps explicitly trusted signing certificates. While the digital signature certificate chains up to the trusted root certification authority, many applications (such Microsoft Office and Windows PowerShell) are required to store a particular signing certificate in this container in order to trust signatures from that particular signer. This means that a digital signature-aware application can trust one signing certificate but not trust another signing certificate even if both certificates are issued by the same certification authority.
Untrusted Certificates (Disallowed) — This container keeps explicitly untrusted certificates. If you decide to not trust either a particular certificate or all certificates issued by a particular certification authority, just add these certificates to this container. By default, this container already contains two certificates. It is strongly recommended to NOT REMOVE them from the container. For additional info read the following article: http://support.microsoft.com/kb/293817.
Third-Party Root Certification Authorities (AuthRoot) — This certificate container is similar to the Trusted Root Certification Authorities. It keeps the certificates from the Microsoft Root Certificate Program. For more information about the Microsoft Root Certificate program, read the following article: http://support.microsoft.com/kb/931125.
Trusted People (TrustedPeople) — This container keeps certificates issued to people or end entities that are explicitly trusted. Most often, these are self-signed certificates or certificates explicitly trusted in an application such as Microsoft Outlook. To share an EFS–encrypted file with other parties, you must have their certificate in this store.
Certificate Enrollment Requests (REQUEST) — This container stores certificate enrollment requests until these requests are submitted to the certification authority. When a certification authority issues a certificate in response to a request, you need to install the certificate to this container using a special utility, such CertReq.exe. After that, the certificate enrollment request is transferred to the Personal (My) container as a certificate.
Smart Card Trusted Roots (SmartCardRoot) — This container is used to store trusted smart card certificates.
Other People (AddressBook) — This container maintains certificates that have been added to an Outlook contact.
Active Directory User Object (UserdDS) — This container is used to store certificates associated with a user object and published in Active Directory. The content of this container is equal to the certificates that are shown in the advanced view of the Active Directory Users and Computers console when the properties of a user object are viewed.
Let's get this out of the way... I :
use Visual Studio 2012
develop VB.NET applications - mostly .NET framework 3.5, some 2.0.
use Windows 7 for development (users are also using Windows 7. There are a small number of internal users (less than 40).
I am also going to state that I am new at this and don't fully understand this process. I do understand the underlying concepts of encryption/hashing/keys etc., but I can't tell you why you might need a .cer file and not a .pfx file.
Now then...
We have an application that uses a certificate to sign its manifest that has worked for three (or so) years. We recently upgraded from Visual Studio 2008 to Visual Studio 2012, having basically skipped Visual Studio 2010. Somewhere in that process the certificate is now invalid or corrupted.
The proposed solution: Make a new one with makecert.exe "just like we did last time". No sense paying for a certificate when all we need it for is our own small set of users and the small convenience of not seeing that "do you trust this publisher?" message (I think?).
When trying to publish, the exact error is:
Cannot publish because a project failed to build.
An error occurred while signing: Failed to sign
bin\Release\app.publish\setup.exe. SignTool Error: The signer's
certificate is not valid for signing. SignTool Error: An error
occurred while attempting to sign: bin\Release\app.publish\setup.exe
Now, the article Support Certificates In Your Applications With The .NET Framework 2.0 says:
for desktop applications, you typically install certificates in the
user store.
So when I look at the user store (via MMC with certificate snap-in) I see:
Where the red line is is the OLD/INVALID certificate. One other one is still unexpired, with my username on it (2013-06-20).
When I go to select from the store, I see this:
And in case you are curious, the other intuitive place to put one of these looks like this:
So how do I add another one where the old/bad one is?
Here is what I have tried:
Following these instructions, I executed
makecert -n "CN=TempCA" -r -sv TempCA.pvk TempCA.cer
Now I have a .pvk file, and a .cer file. Then I followed the instructions in Pvk2Pfx (Windows Drivers) and ran
pvk2pfx.exe -pvk TempCA.pvk -spc TempCA.cer -pfx TempCA.pfx
Now I have a .pfx file... (is this what I need?), but when trying to import to the certificate store using MMC, the password I used is supposedly wrong no matter what - even if I copy and paste it in. (It sounds like a bug in the import program... I can reproduce this.)
Trying another route, after importing the .cer file, it will not show up in the "select from store" window in Visual Studio, so that's useless.
I've spent a day on this and am ready to give up, but I can't. What do I need to do?
The article Using Makecert to Create Certificates for Development helped about 90% of the way...
The rest was understanding that I could do one of two things (both of these options require the certificate must be in a "trusted root" area like "Trusted Root Certification Authority", or must be signed by one that is there):
In Visual Studio, under the "signing" tab I could just use "Select from file" and use the .cer file.
If I just put my .cer file in the "personal" folder, it will appear as an option from the "select from store" button (I may need to restart the computer or Visual Studio).
The answer by Watki02 is quite helpful but missing a few details. Also, key information in that blog post should also be posted here. So...
Create your own root authority certificate:
CD \path\to\whereyouwant
makecert -n "CN=Make Up A Name" -a sha1 -r -sv MakeUpANameCertificateAuthority.pvk MakeUpANameCertificateAuthority.cer -ss MakeUpANameCertificateAuthority -sr localMachine
Password prompts
You will be prompted to create a password and then submit a password. I used the same password for both prompts
User certificate
makecert -pe -n "CN=CN=Make Up A Name User" -ss MY -a sha1 -iv MakeUpANameCertificateAuthority.pvk -ic MakeUpANameCertificateAuthority.cer -sv MakeUpAName.pvk MakeUpAName.cer
Password prompts again
I used the same password as above again
Make a portable file for exchange
pvk2pfx -pvk "MakeUpAName.pvk" -spc "MakeUpAName.cer" -pfx "MakeUpAName.pfx" -pi SamePasswordAgain
Send the file to your private clients
"MakeUpAName.pfx"
Install the certificate
c:> MMC.EXE
MENU FILE -> Add / Remove Snapin
Certificates -> Add -> Computer Account -> Finish -> OK
MENU Action->All Tasks->Import
Go through the wizard
Choose *.pfx format
Choose file
Continue with default options