I am trying to create a new self signed cert and then use it to sign an EXE, to address the fact that idiot Autodesk is using an installer that ignores the time stamp and refuses to install something with an expired cert, even their own installer. It's a bug, they know it, and they fixed their installer. But addressing that when you have 30+ deployments that use the old buggy one is a PITA. Anyway...
I expected this would produce a certificate that I would find in the Personal tab.
$certParameters = #{
'DnsName' = 'PxTools'
'Type' = 'CodeSigningCert'
'CertStoreLocation' = 'Cert:\LocalMachine\My'
'NotAfter' = (Get-Date).AddMonths(12)
'KeyAlgorithm' = 'RSA'
'KeyLength' = '4096'
}
$cert = New-SelfSignedCertificate #certParameters
and that I would then be able to use it for signing. But it doesn't populate the $cert variable as expected, and it puts the cert in Intermediate Certification Authorities, and I have yet to figure out how to use
Get-ChildItem cert:\LocalMachine\?? -codesign
To get certs in that location. I have used ??=My to get a cert in Personal, but not sure
A: Why the cert isn't created in Personal as expected
B: How to get the cert from where it IS created
Related
I am currently making a RootCA and a SAN cert using powershell.
Now everything is working as it should only it seems soms browsers are pretty strict when it comes to trusting a certificate. I am currently getting one last error when running my certificate through a linter (Z-lint in this case).
zlint ERROR Root CA Certificate: extendedKeyUsage MUST NOT be present.t
Now the error is pretty obvious... extendedKeyUsage should not be present in my powershell command when creating my RootCA
However I only use -keyUsage in my command. I am not quite sure what I need to adjust to my command to remove the error.
$rootCert = New-SelfSignedCertificate -CertStoreLocation cert:\LocalMachine\My -keyUsage KeyEncipherment,DigitalSignature,CrlSign,CertSign -Subject "CN=AgionRootCA, OU=supplied, O=supplied, C=supplied, L=supplied, S=supplied" -TextExtension #("1.3.6.1.4.1.311.21.10={text}1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2", "2.5.29.19={text}CA=true","2.5.29.37={text}1.3.6.1.4.1.311.10.12.1")
After following ->
When looking at the Microsoft Docs for the New-SelfSignedCertificate cmdlet it says the following about the -KeyUsage switch:
Specifies the key usages set in the key usage extension of the certificate.
The acceptable values for this parameter are:
CertSign
CRLSign
DataEncipherment
DecipherOnly
DigitalSignature
EncipherOnly
KeyAgreement
KeyEncipherment
None (default)
NonRepudiation
The default value, None, indicates that this cmdlet does not include the KeyUsage
extension in the new certificate.
So it would seem like that if you want extendedKeyUsage to NOT be present you need to change -keyUsage KeyEncipherment,DigitalSignature,CrlSign,CertSign to -keyUsage None which would be default if you don't include the switch at all.
The error messages increased stating that I do need regular -KeyUsage, but not -extendedKeyUsage
Error messages:
zlint ERROR Root and Subordinate CA certificate keyUsage extension's crlSign bit MUST be set
zlint ERROR Root CA Certificate: Bit positions for keyCertSign and cRLSign MUST be set.
zlint ERROR Root CA Certificate: extendedKeyUsage MUST NOT be present.t
Well I managed to solve the problem.
In my Powershell command I had added the OID 2.5.29.37 at the end and apparently
OID 2.5.29.37 is ExtendedKeyUsage. Therefore I kept on getting that problem. Closed!
More information on this matter Self signed certificates
I would like to create a Private Key and a CSR, submit the CSR to a Certificate Authority, retrieve the certificate once issued, and have the Private Key and Certificate as separate PEM files suitable for use in non-Microsoft applications (they are generally web servers). I'd like to avoid using Java Keytool or OpenSSL to generate keys and certificate signing requests in Windows PowerShell on Windows Server 2016. The CSRs will be submitted to a Microsoft Active Directory Certificate Services.
OpenSSL and Java are not (and won't be) installed on the computers requiring certificates. As the certificates are for non-Microsoft applications, I also want to avoid using the Certificate Store on the computers. I don't mind using "certreq" to actually submit the completed CSR and retrieve the resulting certificate once approved.
I have some code, based on C# Export Private/Public RSA key from RSACryptoServiceProvider to PEM string, which will extract the private key from an X509Certificate2. So far, as an experiment, I have used this successfully with a PKCS12 keystore (where the key and CSR were created with Keytool).
Inspired by Automate the process of creating a private key, a CSR and a final Signed Certificate in .NET Core I knocked together the following, but ran out of inspiration, and didn't really know what I was doing. How do I complete the process of submitting the CSR to the CA (or outputting the CSR as a file for using with certreq)?
[int]$KeyLength = 2048
$ComputerName = "jon"
$Domain = "domain.local"
[string]$DistinguishedName = "CN=$($ComputerName).$($Domain),OU=Unit,O=Org,C=GB"
$HashAlgo = [System.Security.Cryptography.HashAlgorithmName]::SHA256
$RSASigPadding = [System.Security.Cryptography.RSASignaturePadding]::Pkcs1
$RSAKey = [System.Security.Cryptography.RSA]::Create($KeyLength)
$Certificate = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new($DistinguishedName,$RSAKey,$HashAlgo,$RSASigPadding)
# Add Basic Constraints
$BasicConstraints = [System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension]::new($false,$false,0,$false)
$BCExtension = [System.Security.Cryptography.X509Certificates.X509Extension]::new($BasicConstraints,$false)
$Certificate.CertificateExtensions.Add($BCExtension)
# Add Subject Key Identifier extension
$SubjectKeyIdentifier = [System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension]::new($Certificate.PublicKey,$false)
$SKIExtension = [System.Security.Cryptography.X509Certificates.X509Extension]::new($SubjectKeyIdentifier,$false)
$Certificate.CertificateExtensions.Add($SKIExtension)
# Add Key Usage
$KeyUsageFlags = [System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::DigitalSignature -bor [System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::KeyEncipherment
$KeyUsage = [System.Security.Cryptography.X509Certificates.X509KeyUsageExtension]::new($KeyUsageFlags,$true)
$KUExtension = [System.Security.Cryptography.X509Certificates.X509Extension]::new($KeyUsage,$true)
$Certificate.CertificateExtensions.Add($KUExtension)
# Add EKU
$ServerAuthentication = [System.Security.Cryptography.Oid]::New("Server Authentication")
$EKUOidCollection = [System.Security.Cryptography.OidCollection]::new()
$EKUOidCollection.Add($ServerAuthentication) | out-null # this outputs 0
$EnhancedKeyUsage = [System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]::new($EKUOidCollection,$false)
$EKUExtension = [System.Security.Cryptography.X509Certificates.X509Extension]::new($EnhancedKeyUsage,$false)
$Certificate.CertificateExtensions.Add($EKUExtension)
# Add SAN
$SubjectAlternateNameBuilder = [System.Security.Cryptography.X509Certificates.SubjectAlternativeNameBuilder]::new()
$SubjectAlternateNameBuilder.AddDnsName("$($ComputerName).$($Domain)")
$Certificate.CertificateExtensions.Add($SubjectAlternateNameBuilder.Build())
Previously we have one code signing cert, every thing working fine. Recently cert expired so we taken new cert from Comodo and released new build with that cert.
So here is the problem: Package Family Name Changed with that new cert, so I am not able to upgrade old installed apps with this new build packaged with new cert.
Need solution for this to maintain Package Family Name as constant or for new cert's also we need to provide upgrade for older apps.
How can we achieve this?
Error msg while upgrading package from PowerShell:
Add-AppxPackage : Deployment failed with HRESULT: 0x80073CF3, Package failed
updates, dependency or conflict validation.
Windows cannot install package df70dbc9-455c-4c32-b052-7ac2943630b7_1.0.193.1_x64__qbsrcgy0j364g
because a different package df70dbc9-455c-4c32-b052-7ac2943630b7_1.0.0.191_x64__hs446qhh7vdt4
with the same name is already installed. Remove package
df70dbc9-455c-4c32-b052-7ac2943630b7_1.0.0.191_x64__hs446qhh7vdt4 before
installing.
NOTE: For additional information, look for [ActivityId]
b0deec37-ac10-0001-81fd-deb010acd101 in the Event Log or use the command line
Get-AppxLog -ActivityID b0deec37-ac10-0001-81fd-deb010acd101
At C:\Users\\Desktop\\myappName_1.0.193.1_x64_Test\Add-AppDevPackage.ps1:388 char:13
+ Add-AppxPackage -Path $DeveloperPackagePath.FullName -DependencyPath ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\Users\myuser....193.1_x64.appx:String) [Add-AppxPackage], IOException
+ FullyQualifiedErrorId : DeploymentError,Microsoft.Windows.Appx.PackageManager.Commands.AddAppxPackageCommand
Error: Could not install the app.
The Package Family Name (PFN) suffix (in your case hs446qhh7vdt4) is a hash of the certificate's subject (AKA subject name):
certutil -dump foo.pfx
Enter PFX password:
================ Certificate 0 ================
================ Begin Nesting Level 1 ================
Element 0:
Serial Number: xxxxxxxxxxxxxxxxx
Issuer: CN=Microsoft, O=Contoso, L=Redmond, S=Washington, C=US
NotBefore: 11/1/2016 12:00 AM
NotAfter: 11/1/2017 12:00 AM
Subject: CN=Microsoft, O=Contoso, L=Redmond, S=Washington, C=US <== THIS IS HASHED
If you make sure the new cert you generate has the same subject, you'll get the same PFN. Note that you might not be able to generate store certs from within Visual Studio (at the time of writing, it can't parse complex subjects like the one above with multiple 'parts' like CN=X, O=Y). In that case you'll have to create your own, but it must comply with the store validations.
Luckily, there's a simple command that generates the exact certificate you need. Open a Visual Studio developer prompt and run (one line):
makecert -sv foo.pvk -n "CN=Contoso, O=Contoso, L=Redmond, S=Washington, C=US"
foo.cer -b 11/01/2016 -e 11/01/2017 -r -cy end -a sha256 -eku 1.3.6.1.5.5.7.3.3
Make sure to replace the validity dates (no more than a year apart!) as well as the subject (taken from your previous cert using certutil -dump). The names of the output cert (cer) and private key (pvk) are meaningless. That command will generate foo.pvk and foo.cer, which you will then be able to combine to a pfx like so:
PVK2PFX -pvk foo.pvk -spc foo.cer -pfx foo.pfx
Another option for advanced generation
In case you have more advanced cert requirements, you should be able to use certreq (haven't tested it though). Create a file named cert.inf with the following contents:
[Version]
Signature = "$Windows NT$"
[Strings]
szOID_ENHANCED_KEY_USAGE = "2.5.29.37"
szOID_CODE_SIGNING = "1.3.6.1.5.5.7.3.3"
szOID_BASIC_CONSTRAINTS2 = "2.5.29.19"
[NewRequest]
Subject = "CN=Contoso, O=Contoso, L=Redmond, S=Washington, C=US"
Exportable = true
HashAlgorithm = Sha256
KeyLength = 2048
RequestType = Cert
ValidityPeriod = "Years"
ValidityPeriodUnits = "1"
[Extensions]
%szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_CODE_SIGNING%"
%szOID_BASIC_CONSTRAINTS2% = "{text}"
Replace the subject and validity period, and adjust any advanced settings you need per the docs (or more likely found on the web). Then do the following:
certreq -new cert.inf cert.cer
Double-click the resulting cert.cer and install it to the Trusted Root Certificate Authorities store (either user or machine).
certreq -accept -user cert.cer OR certreq -accept -machine cert.cer (depending on the store you picked in the previous step).
Go to the Personal store in the cert manager (user or machine scope, depending on what you picked above) and find the cert you just installed. Double-click it and copy the serial number from the details tab (I encountered some voodoo here where the cert would only show up after a long time, or after I installed a different cert (with a different subject name).
certutil -exportpfx -p "YOUR_PFX_PASS" my SERIAL_NUMBER foo.pfx (replace the password and the serial number with their actual values)
You should now have a valid store pfx.
Yet another option for even more advanced generation
Use OpenSSL. Pretty sure it can do all the above and more, but I haven't tried it personally so you'll have to figure it out - and hopefully share here once you do!
In the identity server samples we find code like this in Startup.cs
var certFile = env.ApplicationBasePath + "\\idsrv3test.pfx";
var signingCertificate = new X509Certificate2(certFile, "idsrv3test");
How would I go about replacing this for production scenarios?
For the record, the code proposed in the image posted by RuSs:
options.SigningCertificate = LoadCertificate();
public X509Certificate2 LoadCertificate()
{
string thumbPrint = "104A19DB7AEA7B438F553461D8155C65BBD6E2C0";
// Starting with the .NET Framework 4.6, X509Store implements IDisposable.
// On older .NET, store.Close should be called.
using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates.Find(X509FindType.FindByThumbprint, thumbPrint, validOnly: false);
if (certCollection.Count == 0)
throw new Exception("No certificate found containing the specified thumbprint.");
return certCollection[0];
}
}
Get a dedicated cert - either via your PKI or self-generate one:
http://brockallen.com/2015/06/01/makecert-and-creating-ssl-or-signing-certificates/
Import the key pair into the Windows certificate store, and load it from there at runtime.
To step up security, some people deploy the keys to a dedicated device (called an HSM) or to a dedicated machine (e.g. behind a firewall). The ITokenSigningService allows moving the actual token signing to that separate machine.
Recently I decided to revamp my token signing issuing process. If you're running Windows 10, you can use the awesome powershell cmdlet called New-SelfSignedCertificate.
Here is my example usage:
New-SelfSignedCertificate -Type Custom
-Subject "CN=TokenSigningForIdServer"
-TextExtension #("2.5.29.37={text}1.3.6.1.5.5.7.3.3")
-KeyUsage DigitalSignature
-KeyAlgorithm RSA
-KeyLength 2048
-CertStoreLocation "Cert:\LocalMachine\My"
Make sure you are running the command as an admin. You can obtain the certificate details by opening certlm.msc. It should be stored below Personal\Certificates.
Most of the flags should be obvious, apart from the -TextExtention one. It specifies that an Enhaced Key Usage field is set to the "Code Signing" value. You can play around with the algorithm used, key length, even add extentisons by refering to the following documentation page.
Here is how I load it from a thumbprint in my config:
Click here to see image
Is it possible to set Key Usage attributes using makecert, or any other tool I can use to generate my own test certificates?
The reason I'm interested is that certificates used for BizTalk Server AS2 transport require a key usage of Digital Signature for signing and Data Encipherment or Key Encipherment for encryption/decryption, and I want to play around with this feature.
I see how to set enhanced key usage attributes with makecert, but not key usage.
While you cannot make a self-signed cert and set the Enhanced Key Usage parameters using makecert I thought I'd save everyone the trouble of trying to use go down the path of using OpenSSL to generate a cert on Windows. Instead, you can use certreq (which is available if you already have makecert) and fashion your own request to set the required parameters.
For example, this sets up a cert with an EKU of Document Encryption (1.3.6.1.4.1.311.80.1) and key usages of Key Encipherment and Data Encipherment.
Create a new file, MyCert.inf:
[Version]
Signature = "$Windows NT$"
[Strings]
szOID_ENHANCED_KEY_USAGE = "2.5.29.37"
szOID_DOCUMENT_ENCRYPTION = "1.3.6.1.4.1.311.80.1"
[NewRequest]
Subject = "cn=me#example.com"
MachineKeySet = false
KeyLength = 2048
KeySpec = AT_KEYEXCHANGE
HashAlgorithm = Sha1
Exportable = true
RequestType = Cert
KeyUsage = "CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DATA_ENCIPHERMENT_KEY_USAGE"
ValidityPeriod = "Years"
ValidityPeriodUnits = "1000"
[Extensions]
%szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_DOCUMENT_ENCRYPTION%"
Just set the Subject to whatever you need.
Then run:
certreq -new MyCert.inf MyCert.cer
This will generate the public key (X509 cert) and install it to your Current User personal store on the machine. You can export it from there if you want.
I used this to generate a certificate for encrypting PowerShell DSC, for testing.
For more details: https://technet.microsoft.com/en-us/library/dn296456.aspx#BKMK_New
Digital Signature,Data Encipherment and Key Encipherment can be add by using the PowerShell Cmdlet New-SelfSignedCertificate. One of the New-SelfSignedCertificate Parameters is KeyUsagewhere you can add DigitalSignature, DataEncipherment and KeyEncipherment.
New-SelfSignedCertificate is described on technet (https://technet.microsoft.com/library/hh848633)
Sample:
New-SelfSignedCertificate -Type Custom -Subject "CN=sample.com" -KeyUsage DataEncipherment, KeyEncipherment, DigitalSignature -TextExtension #("2.5.29.37={text}1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1") -CertStoreLocation "Cert:\CurrentUser\My"
The sample covers client authentication and server authentication and creates the certificate at the current user store under my.
MakeCert doesn't let you specify key usage, only extended key usage. I think you need a CA to create a broader certificate.
You can setup your own CA with ubuntu server. https://www.digitalocean.com/community/tutorials/how-to-create-a-ssl-certificate-on-apache-for-ubuntu-14-04
You can use the -eku option to specify the key usage to your certificate.
See details here:
http://msdn.microsoft.com/en-us/library/aa386968(VS.85).aspx