Setting Key Usage attributes with Makecert - certificate

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

Related

Generating private key in a file using certreq in powershell

I am using a powershell script to create Certificate Signing Request (CSR) using certreq. I need the private key in a file but the script is not generating that. I tried looking the documentation of certreq and other resources but found nothing. In INF setting I am setting Exportable = TRUE. here is the setting
$settingsInf = "
[Version]
Signature=`"`$Windows NT`$
[NewRequest]
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
RequestType = PKCS10
ProviderName = `"Microsoft RSA SChannel Cryptographic Provider`"
ProviderType = 12
HashAlgorithm = sha256
;Variables
Subject = `"CN={{CN}},CN={{CN2}},O={{O}},DC={{DC}},DC={{DC2}}`"
[Extensions]
{{SAN}}
Another solution I tried is to use openssl to get private key and CSR. In this solution I am getting both private key and CSR but when I submit the CSR to CA then it throws following error
"message" : "Invalid Subject DN. The requested Subject DN is not compatible with the issuing CA.",
I am using openssl as follows
$subject = "`"/CN=$cn/CN=$cn2/O=$o/DC=$dc/DC=$dc2'"
openssl req -new -key $privateKeyPath -rand $randPath -subj $subject -out $csrPath
The Certificate Authority DN is as follows
"issuer_dn" : "CN=usa,O=SE,DC=abc,DC=com",
any suggestion to either get private key using certreq or why CA is throwing error when using openssl. Thanks
I found the solution. may be it will help someone else.
It appears that some CA require subject in a particular order which is not documented (Super Annoying).
The CA I was connected to require $subject in following way
$subject = "`"/DC=$dc2/DC=$dc/O=$o/CN=$cn2/CN=$cn'"
using subject like this in generating CSR is accepted by CA.

Powershell creating new self signed certificate. Root CA Certificate: extendedKeyUsage MUST NOT be present.t

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

Create certificate and CSR using Windows PowerShell/.Net without using external programs or libraries

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())

How would I generate the Identity Server signing certificate

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

add or create 'Subject Alternative Name' field to self-signed certificate using makecert

How can I create a certificate using makecert with a 'Subject Alternative Name' field ?
You can add some fields eg, 'Enhanced Key Usage' with the -eku option and I've tried the -san option but makecert doesn't like it.
This is a self-signed certificate so any method that uses IIS to create something to send off to a CA won't be appropriate.
An even easier way is to use the New-SelfSignedCertificate PowerShell commandlet, which includes a SAN by default. In a single command you can create the certificate and add it to the store.
New-SelfSignedCertificate -DnsName localhost -CertStoreLocation cert:\LocalMachine\My
Note that you need to run PowerShell as an administrator.
Makecert doesn't appear to support SANs so I created a certificate with SANs for use with IIS using OpenSSL. Check out my blog post about it:
IIS 7 provides some easy to use wizards to create SSL certificates,
however not very powerful ones. What I needed to do was to create SSL
certificates that included a x.509 V3 extension, namely subject
alternative names, a.k.a SANs. What SANs do is allow the website
certificate to validate incoming requests by more than one URL domain
name. This is really important when the web server is running web
services such as WCF services and when other web services connect to
them over SSL connections as with service oriented architectures.
Unless special code is added to the web services to override the
default SSL validation handler routines, the common name (CN) of the
certificate MUST match the incoming request URL domain. So if the
request was made using an FQDN, the certificate must have the FQDN as
a CN or a SAN, a IP address or just a hostname will cause an SSL
validation error and the connection will fail.
SANs to the rescue… SANs support, among other things, DNS names and IP
addresses. So by creating the certificate with SANs of the server FQDN
and IP address, it increases the ways that other web services can
connect.
There are a number of tools that can generate certificates:
makecert.exe, keytool.exe (java), selfssl.exe and openssl.exe. In
addition, starting with Windows Vista and Server 2008 Microsoft added
the CertEnroll API which can also create certificates programmatically
either through COM interfaces.
OpenSSL ended up doing exactly what I needed it to do. The process was
fairly straight forward.
Construct an OpenSSL config file.
[req] distinguished_name = req_distinguished_name x509_extensions =
v3_req prompt = no [req_distinguished_name] C = US ST = VA L =
Somewhere O = MyOrg OU = MyOU CN = MyServerName [v3_req] keyUsage =
keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth
subjectAltName = #alt_names [alt_names] DNS.1 = MyServerName DNS.2 =
10.0.1.34 IP.1 = 10.0.1.34 IP.2 = 192.167.20.1
Create x509 request with OpenSSL
openssl.exe req -x509 -nodes -days 730 -newkey rsa:2048 -keyout
C:\cert.pem -out C:\cert.pem -config C:\PathToConfigFileAbove.txt
Create a PFX containing the keypair
openssl.exe pkcs12 -export -out C:\cert.pfx -in C:\cert.pem -name "My
Cert" -passout pass:mypassword
Import the PFX into IIS using the import link in the server
certificates area.
Bind the certificate to the IIS websites.
And viola, we know have a SSL certificate for IIS with SANs so we can
connect using multiple domain names without certificate validation
errors.
Source: Creating certificates with SANs using OpenSSL by Andy Arismeti, Thursday, September 1, 2011
Update
The certificate generated using the below makecert method does not work reliably in all browsers, because it does not actually generate a "Subject Alternative Name".
If you examine the certificate you will see that it does not actually have a Subject Alternative Name field, but instead specifies multiple CN in the Subject field.
E.g.
Subject:
CN = blah.foo.corp
CN = blah
Whereas a real "SAN" cert would have something like:
Subject Alternative Name:
DNS Name=blah.foo.corp
DNS Name=blah
To understand the differences and history between the "Subject" field with "Common Name" and the "Subject Alternative Name" field, I recommend reading The (soon to be) not-so Common Name.
So it appears that makecert cannot be used to generate a true "SAN" cert, and you will need to use other tools, such as openssl.
Original Answer:
At least with the version of makecert that comes with Visual Studio 2012, you can specify multiple subjects, simply by specifying a comma separated list -n "CN=domain1, CN=domain2"
E.g. (from the technet blog Makecert.exe SAN and Wildcard certificate)
makecert -r -pe -n "CN=*.fabrikam.com, CN=*.contoso.com" -b 01/01/2010 -e 01/01/2100 -eku 1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.3,1.3.6.1.5.5.7.3.4 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -len 2048