OpenSSL Certificate (Version 3) with Subject Alternative Name - certificate

I'm using the OpenSSL command line tool to generate a self signed certificate. It seems to be working correctly except for two issues. I can't get it to create a .cer with a Subject Alternative Name (critical) and I haven't been able to figure out how to create a cert that is Version 3 (not sure if this is critical yet but would prefer learning how to set the version).
Has anyone done this successfully? The default config (.cfg) file has seemingly clear documentation (seen below):
This stuff is for subjectAltName and issuerAltname.
Import the email address.
subjectAltName=email:copy
However this does not work. My hunch is that the subject Alternative Name is not showing up b/c it is not present in the V1 specs, which is why I'm also pursuing setting the version.
Here is the config file I'm using:
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
emailAddress = myEmail#email.com
req_extensions = v3_req
x509_extensions = v3_ca
[req_distinguished_name]
C = [Press Enter to Continue]
C_default = US
C_min = 2
C_max = 2
O = [Press Enter to Continue]
O_default = default
0.OU=[Press Enter to Continue]
0.OU_default = default
1.OU=[Press Enter to Continue]
1.OU_default = PKI
2.OU=[Press Enter to Continue]
2.OU_default = ABCD
commonName = Public FQDN of server
commonName_max = 64
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
subjectAltName = email:myEmail#email.com
issuerAltName = issuer:copy

Here is the simple steps for you
While generating the CSR you should use -config and -extensions
and while generating certificate you should use -extfile and -extensions
Here is the example:
openssl req -new -nodes -keyout test.key -out test.csr -days 3650 -subj "/C=US/ST=SCA/L=SCA/O=Oracle/OU=Java/CN=test cert" -config /etc/pki/tls/openssl.cnf -extensions v3_req
openssl x509 -req -days 3650 -in test.csr -CA cacert.pem -CAkey rootCA.key -CAcreateserial -out test.pem -extfile /etc/pki/tls/openssl.cnf -extensions v3_req
hope this helps

Alright, none of the other answers on this page worked for me, and I tried every last one of them. What worked for me was a little trick:
when requesting the cert:
-config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-reqexts SAN
and when signing the cert:
-extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-extensions SAN
Notice that this is a bash trick, <(some comamnds) makes the stdout output of some commands show as a temp file to the outer commands in bash.
So there is no confusion, here is a working script that covers everything from the start, including creating a certificate authority:
# if the server name is undefined, lets default to 'Some-Server'
SERVER="${SERVER:-Some-Server}"
CORPORATION=My-Corp
GROUP=My-Corporate-Group
CITY=City
STATE=State
COUNTRY=US
CERT_AUTH_PASS=`openssl rand -base64 32`
echo $CERT_AUTH_PASS > cert_auth_password
CERT_AUTH_PASS=`cat cert_auth_password`
# create the certificate authority
openssl \
req \
-subj "/CN=$SERVER.ca/OU=$GROUP/O=$CORPORATION/L=$CITY/ST=$STATE/C=$COUNTRY" \
-new \
-x509 \
-passout pass:$CERT_AUTH_PASS \
-keyout ca-cert.key \
-out ca-cert.crt \
-days 36500
# create client private key (used to decrypt the cert we get from the CA)
openssl genrsa -out $SERVER.key
# create the CSR(Certitificate Signing Request)
openssl \
req \
-new \
-nodes \
-subj "/CN=$SERVER/OU=$GROUP/O=$CORPORATION/L=$CITY/ST=$STATE/C=$COUNTRY" \
-sha256 \
-extensions v3_req \
-reqexts SAN \
-key $SERVER.key \
-out $SERVER.csr \
-config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-days 36500
# sign the certificate with the certificate authority
openssl \
x509 \
-req \
-days 36500 \
-in $SERVER.csr \
-CA ca-cert.crt \
-CAkey ca-cert.key \
-CAcreateserial \
-out $SERVER.crt \
-extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-extensions SAN \
-passin pass:$CERT_AUTH_PASS
We can then verify that the Subject Alternative name is in the final cert:
openssl x509 -in Some-Server.crt -text -noout
The pertinent section is:
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:Some-Server
So it worked! This is a cert that will be accepted by every major browser (including chrome), so long as you install the certificate authority in the browser. Thats ca-cert.crt that you will need to install.
Here is a sample configuration for nginx that would allow you to use the cert:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost:443;
ssl_certificate /etc/ssl/certs/Some-Server.crt;
ssl_certificate_key /etc/ssl/private/Some-Server.key;
ssl_dhparam /etc/ssl/certs/https-dhparam.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}

I got it to work with the following version (emailAddress was incorrectly placed) :
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
req_extensions = v3_req
x509_extensions = v3_ca
[req_distinguished_name]
C = [Press Enter to Continue]
C_default = US
C_min = 2
C_max = 2
O = [Press Enter to Continue]
O_default = default
0.OU=[Press Enter to Continue]
0.OU_default = default
1.OU=[Press Enter to Continue]
1.OU_default = PKI
2.OU=[Press Enter to Continue]
2.OU_default = ABCD
commonName = Public FQDN of server
commonName_max = 64
emailAddress = [Press Enter to Continue]
emailAddress_default = myEmail#email.com
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
subjectAltName = email:myEmail#email.com
issuerAltName = issuer:copy
Notes:
To generate the certificate I used:
openssl req -config req.cnf -new -nodes -out req.pem -x509
I haven't seen much use for issuerAltname (if you have I'd be interested to know where).
Using issuer:always isn't recommended for authorityKeyIdentifier.
Using email:copy now works with subjectAltName.
v3_req section is superfluous (as well as req_extensions line.

I just developed a web based tool that will generate this command automatically based on form input and display the output.
UPDATE: see certificatetools.com
It became so popular that I improved it and published it under its own domain name.
It will not only give you the downloadable .csr, but also provide the openssl commands that were used to generate it, and the needed openssl.cnf configuration options.
Example:
OpenSSL Commands
#generate the RSA private key
openssl genpkey -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out priv.key
#Create the CSR
openssl req -new -nodes -key priv.key -config csrconfig.txt -out cert.csr
OpenSSL CSR Config
[ req ]
default_md = sha256
prompt = no
req_extensions = req_ext
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
commonName = example.com
countryName = US
stateOrProvinceName = Louisiana
localityName = Slidell
organizationName = Acme Inc.
[ req_ext ]
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=critical,serverAuth,clientAuth
subjectAltName = #alt_names
[ alt_names ]
IP.0 = 1.1.1.1
IP.1 = 2.2.2.2
DNS.0 = server1.example.com
DNS.1 = server2.example.com
email.0 = email1#example.com
email.1 = email2#example.com

What command did you use to make the CSR certificate request? What command did you use to make the certificate file? Different answers for different circumstances you know.
Maybe you are not putting
subjectAltName=email:copy
in the section
[v3_req]
Maybe you are using openssl x509 to generate the certificate, if so you must use
-extfile /etc/pki/tls/openssl.cnf
because without that it doesnt use your config file
You also might need
-extensions v3_req
command line switch

I referred to several pages, and the most significant helps are from 1. https://geekflare.com/san-ssl-certificate/, 2. https://certificatetools.com/ (see answer from user40662), and 3. answer from Raghu K Nair about the command usage.
Then my successful try:
san.cnf
[ req ]
default_bits = 2048
default_md = sha256
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName = CN # C=
stateOrProvinceName = Shanghai # ST=
localityName = Shanghai # L=
#postalCode = 200000 # L/postalcode=
#streetAddress = "My Address" # L/street=
organizationName = My Corporation # O=
organizationalUnitName = My Department # OU=
commonName = myname.mysoftware.mycorporation.com # CN=
emailAddress = myname#example.com # CN/emailAddress=
[ v3_req ]
subjectAltName = #alt_names
[ alt_names ]
DNS.1 = myname.mysoftware.mycorporation.com
#DNS.2 = other2.com
#DNS.3 = other3.com
Command:
openssl req -x509 -nodes -days 365 -subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Corporation/OU=My Department/CN=myname.mysoftware.mycorporation.com/emailAddress=myname#example.com" -keyout privateKey.pem -out certificate.crt -config san.cnf -extensions v3_req

The v3_req is required with the entry subjectAltName in the config file. The command
openssl x509 ... -extfile openssl.cnf -extensions v3_req
will insert the SAN into the certificate.

I know this thread is a little old but just in case it works for anyone on windows, check that the file is UTF-8 encoded, in my case I was getting an error indicating there was an error with the .cnf file, so I opened it on Notepad++ set the file encoding to UTF-8, saved, and ran the openssl command again and it made the trick.

#! /bin/dash
# Steps 1-3 show how to use openssl to create a certificate request
# that includes Subject Alternative Names.
# In the uncommon case where you are creating your own CA, steps 4-6
# show how to use openssl to create a CA and then use that CA to
# create a certificate from the request.
# Step 1: Create an OpenSSL configuration file
# to specify the Subject Alternative Names
echo ; echo 'step 1'
cat > foo.cnf <<EOF
[ req ]
distinguished_name = arbitrary_name_1
req_extensions = arbitrary_name_2
[ arbitrary_name_1 ]
[ arbitrary_name_2 ]
subjectAltName = #arbitrary_name_3
[ arbitrary_name_3 ]
DNS.1 = foo.com
DNS.2 = bar.com
DNS.3 = baz.com
EOF
# Step 2: Create a certificate request for foo.com.
#
# openssl
# req
# -config read openssl configuration from this file
# -subj set the commonName of the certificate
# -newkey generate a new key (and, by implication, a new request!)
# -nodes do not encrypt the new private key ("no DES")
# -keyout write the new private key to this file
# -out write the request to this file
echo ; echo 'step 2'
openssl \
req \
-config foo.cnf \
-subj '/CN=foo.com' \
-newkey rsa:2048 \
-nodes \
-keyout foo.key \
-out foo.req
# Step 3: Display the requested extensions.
echo ; echo 'step 3'
openssl req -in foo.req -noout -text | \
grep -A 2 'Requested Extensions:'
# Step 4: Create a certificate authority by creating
# a private key and self-signed certificate.
#
# openssl
# req generate a certificate request, but don't because ...
# -x509 generate a self-signed certificate instead
# -subj set the commonName of the certificate
# -days certificate is valid for N days, starting now
# -newkey generate a new private key
# -nodes do not encrypt the new private key ("no DES")
# -keyout write the new private key to this file
# -out write the self-signed certificate to this file
echo ; echo 'step 4'
openssl \
req \
-x509 \
-subj "/CN=Custom CA" \
-days 4000 \
-newkey rsa:2048 \
-nodes \
-keyout ca.key \
-out ca.cert
# Step 5: Use the certificate authority
# to create a certificate for foo.com.
#
# openssl
# x509 operate on an x509 certificate
# -req create an x509 certificate from a request
# -in read the request from this file
# -CA read the CA certificate from this file
# -CAkey read the CA key form this file
# -extfile read openssl's configuration from this file
# -extensions read extensions from this section of the configuration
# -days certificate is valid for N days, starting now
# -set_serial set the new certificate's serial number
# -out write the new certificate to this file
echo ; echo 'step 5'
openssl \
x509 \
-req \
-in foo.req \
-CA ca.cert \
-CAkey ca.key \
-extfile foo.cnf \
-extensions arbitrary_name_2 \
-days 30 \
-set_serial 1001 \
-out foo.cert
# Step 6: Display the X509v3 extensions:
echo ; echo 'step 6'
openssl x509 -in foo.cert -noout -text | \
grep -A 2 'X509v3 extensions:'

Though after following the steps described here I started .csr files with:
X509v3 Subject Alternative Name
However, my .crt (.pem) files generated with:
openssl x509 -req -in domain.csr -extensions SAN -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out domain.crt -days 100
still were with:
Version: 1 (0x0)
and without:
X509v3 Subject Alternative Name
Solution
Issue was resolved after I switched to this one:
openssl ca -in domain.csr -cert rootCA.pem -keyfile rootCA.key -out domain.crt
I started to get domain.crt files with:
Version: 3 (0x2)
and
X509v3 Subject Alternative Name
If openssl ca complains, you might need to adjust openssl.cnf (or /etc/ssl/openssl.cnf for ubuntu, NOTE: if you used brew install openssl - it will be in a different location) file. Just make sure you properly set these:
[ CA_default ]
dir= /path/to/rootCA/folder # Where everything is kept
certificate= $dir/rootCA.pem # The CA certificate
serial= $dir/rootCA.srl # The current serial number
private_key= $dir/rootCA.key # The private key
And run:
touch /path/to/index.txt
To generate rootCA.srl you can still use the old command:
openssl x509 -req -in domain.csr -extensions SAN -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out domain.crt -days 100
More details on openssl ca can be found here: https://www.openssl.org/docs/man1.0.2/man1/ca.html

Basing on that answer this slightly different approach worked for me:
create a server.cnf-file with:
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = #alt_names
[alt_names]
IP.1 = 127.0.0.1
DNS.1 = localhost
generate your CSR
openssl genrsa -out yourServer_private.key 4096
openssl req -new -key yourServer_private.key -out yourServer.csr
create your certificate and add SAN-information
openssl x509 -req -days 3650 -in yourServer.csr -CA ../Root/Ca.pem -CAkey ../Root/Ca.key -set_serial 01 -out yourServer.pem -extfile server.cnf
check your result
openssl x509 -in yourServer.pem -text
=>
(...)
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
IP Address:127.0.0.1, DNS:localhost
Signature Algorithm: sha256WithRSAEncryption
(...)

Related

Powershell equivalent of 'openssl dgst -sha512 -sign'

For API access, I need to sign a JSON file with 'openssl dgst -sha512 -sign'. I need to run this in a powershell script.
Currently, I am using the following method:
Write the file to a temp file, and re-read it to be certain that there is no conversion problem
Invoke openssl to sign the file
Read the signature file
Call the API
$body = #{
"login" = "customer"
"nonce" = Get-Random -Minimum ([int]([math]::pow(10,8))) -Maximum ([int]([math]::pow(10,9)-1))
"read_only" = "true"
"expiration_time" = "30 seconds"
"label" = "Test"
"global_key" = "true"
} | ConvertTo-Json
Remove-Item -Force "D:\temp\body.tmp" -ErrorAction Continue
Remove-Item -Force "D:\temp\body.dgst" -ErrorAction Continue
$body | Out-File -FilePath "D:\temp\body.tmp" -Encoding ascii
# Re-read data from the file after it's been re-encoded to ascii (as thats what we signed)
$body = [System.IO.File]::ReadAllBytes("D:\temp\body.tmp")
# Sign with the private key of the signing certificate
& D:\apps\openssl\bin\openssl.exe dgst -sha512 -sign "D:\powershell\TransIP\sign.txt" -out "D:\temp\body.dgst" "D:\temp\body.tmp"
$headers = #{
Signature = ([Convert]::ToBase64String([System.IO.File]::ReadAllBytes("D:\temp\body.dgst")))
"Content-Type" = "application/json"
}
I've been searching for a native Powershell/.NET method for SHA512 digest signing, but I can't seem to find anything in the Security class to do this.
Does anyone know a native Powershell method (thus eliminating the dependency of an external openssl installation), or is the above method the only method for signing?
Documentation of the API that I'm trying to use: https://api.transip.nl/rest/docs.html (section 'Authentication'). I've already asked TransIP for support, but they don't support Powershell.
Documentation of 'openssl dgst': https://www.openssl.org/docs/man1.1.1/man1/dgst.html
Joost

How to get the fingerprint of a base64 encoded pfx certificate in windows powershell

I have a base64 encoded .pfx certificate that was encoded in linux using:
cat $my_pfx_cert | base64 -w 0
In windows Powershell, I'm unable to decode this string and produce a meaningful fingerprint however. Below is is my attempt...
$output = "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"
$converted = $([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($output)))
$converted | Out-File -FilePath "$HOME\.ssh\Deadline10RemoteClient_from_bash.pfx"
$cert_password = ""
New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("$HOME\.ssh\Deadline10RemoteClient_from_bash.pfx", $cert_password)
The equivalent in bash however does work:
output="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"
echo "$output" | base64 --decode > "$HOME/.ssh/Deadline10RemoteClient_from_bash.pfx"
openssl pkcs12 -in "$HOME/.ssh/Deadline10RemoteClient_from_bash.pfx" -nodes -passin pass: |openssl x509 -noout -fingerprint
You're likely messing up the encoding when converting it to a string and writing to file with Out-File, so skip that part entirely - the X509Certificate2 constructor takes a raw byte array as input anyway:
$output = "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"
$rawCertBytes = [Convert]::FromBase64String($output)
$certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($rawCertBytes)
Now that you have a [X509Certificate2] object, either read the thumbprint via the API:
$certificate.Thumbprint
Or, if you want to analyze the certificate file on disk (with openssl for example), export it:
# Create a new file
$certFile = New-Item certificate.cer -ItemType File
# Open a writable file stream
$fileStream = $certFile.OpenWrite()
try {
# Write cert bytes to disk
$certBytes = $certificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Cert)
$fileStream.Write($certBytes, 0, $certBytes.Length)
$fileStream.Flush($true)
$fileStream.Close()
}
finally {
# Clean up open file stream
$fileStream |ForEach-Object Dispose
}

How to add postgres as a db in hyperledger fabric-ca using sslmode =verify-ca or verify-full?

I am trying to add postgres as a db in fabric-ca and successfully did it in ssl=require mode but not able to do using ssl=verify-ca or verify-full
my docker-compose.yaml file is like this :
version: '2'
networks:
basic:
services:
orderer.lynkit.io:
container_name: orderer.lynkit.io
image: hyperledger/fabric-orderer:1.4.1
environment:
- ORDERER_GENERAL_LOGLEVEL=DEBUG
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/orderer
command: orderer
ports:
- 7050:7050
volumes:
- ./config/:/etc/hyperledger/configtx
- ./crypto-config/ordererOrganizations/lynkit.io/orderers/orderer.lynkit.io/:/etc/hyperledger/msp/orderer
networks:
- basic
pgadmin4:
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: admin#root.com
PGADMIN_DEFAULT_PASSWORD: SuperSecret
volumes:
- ./pgadmin-data:/var/lib/postgresql/data
ports:
- 80:80
networks:
- basic
ica.consigner.lynkit.io:
image: hyperledger/fabric-ca:1.4.1
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_OPERATIONS_LISTENADDRESS=127.0.0.1:8443
- FABRIC_CA_SERVER_DB_TYPE=postgres
- FABRIC_CA_SERVER_CSR_CN= ica.consigner.lynkit.io
- FABRIC_CA_SERVER_CSR_HOSTS=0.0.0.0
- FABRIC_CA_SERVER_DB_DATASOURCE=host=db-postgres port=5432 user=postgres password=caDbPass12345 dbname=fabriccaserver sslmode=verify-ca
- FABRIC_CA_SERVER_DB_TLS_ENABLED=true
- FABRIC_CA_SERVER_DB_TLS_CERTFILES=[/tmp/postgresCerts/root.crt]
- FABRIC_CA_SERVER_DB_TLS_CLIENT_CERTFILE=/tmp/postgresCerts/server.crt
- FABRIC_CA_SERVER_DB_TLS_CLIENT_KEYFILE=/tmp/postgresCerts/server.key
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
volumes:
- ./crypto-config/peerOrganizations/consigner.lynkit.io/ca/:/etc/hyperledger/fabric-ca-server-config
- ./ca-config/:/etc/hyperledger/fabric-ca-server
# - ./ca-config/ssl/postgres:/etc/hyperledger/fabric-ca-server/ssl
- /home/adarsha/postgresCerts:/tmp/postgresCerts
container_name: ica.consigner.lynkit.io
networks:
- basic
depends_on:
- db-postgres
db-postgres:
container_name: db-postgres
# network_mode: "host"
image: postgres:latest
environment:
- POSTGRES_PASSWORD=caDbPass12345
- POSTGRES_USER=postgres
- POSTGRES_DB=fabriccaserver
volumes:
- ./postgres-test-data:/var/lib/postgresql/data
ports:
- 5432:5432
networks:
- basic
and my postgresql.conf looks like this :
and my hba.conf looks like this :
and i have created a postgrescerts named folder where i created server.key, server.crt, server.csr, root.csr, root.crt, root.key.
using following commands :
openssl req -new -nodes -text -out root.csr -keyout root.key -subj "/CN=ica.consigner.lynkit.io"
chmod og-rwx root.key
openssl x509 -req -in root.csr -text -days 3650 -extfile /etc/ssl/openssl.cnf -extensions v3_ca -signkey root.key -out root.crt
openssl req -new -nodes -text -out server.csr -keyout server.key -subj "/CN=localhost"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 -CA root.crt -CAkey root.key -CAcreateserial -out server.crt
and my ica logs-are like this : --

Import-PfxCertificate no-ops, but no error or anything

I'm trying to import a PFX file into the local certificate store. However, Import-PfxCertificate just does nothing at all. No return value, no error, nothing:
I can double click on the PFX file in Explorer and import it with the same password, which works. Something about the PowerShell CmdLet isn't working. I've also tried other stores, such as Cert:\LocalMachine\My and TrustedPeople. Running it with -Verbose -Debug doesn't show anything extra. Nothing in the Application or Security event logs either. I'm also running as an admin. Ideas?
The Pfx file might have a cert chain. Treating it as a collection would be a better way of handling the certificate store. See installing cert chain for the C# this was based off;
[string] $certPath = '.\test.pfx';
[string] $certPass = 'MyPassword';
# Create a collection object and populate it using the PFX file
$collection = [System.Security.Cryptography.X509Certificates.X509Certificate2Collection]::new();
$collection.Import($certPath, $certPass, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet);
try {
# Open the Store My/Personal
$store = [System.Security.Cryptography.X509Certificates.X509Store]::new('My');
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite);
foreach ($cert in $collection) {
Write-Host ("Subject is: '{0}'" -f $cert.Subject )
Write-Host ("Issuer is: '{0}'" -f $cert.Issuer )
# Import the certificate into an X509Store object
# source https://support.microsoft.com/en-au/help/950090/installing-a-pfx-file-using-x509certificate-from-a-standard-net-applic
if ($cert.Thumbprint -in #($store.Certificates | % { $_.Thumbprint } )) {
Write-Warning "Certificate is already in the store"
# Force the removal of the certificate so we have no conflicts, not required if this is the first install
$store.Remove($cert)
}
# Add in the certificate
$store.Add($cert);
}
} finally {
if($store) {
# Dispose of the store once we are done
$store.Dispose()
}
}

Export certificate from object with private key Export-Clixml

I'm trying to store a few objects as Clixml from PowerShell.
I can successfully store my array and certificate, but the private key is not exported with it.
Example:
PS > $cert.HasPrivateKey
true
PS > $outObject = $array
PS > $outObject += $cert
PS > $outObject | Export-Clixml -Path .\file.xml
PS > $inObject = Import-Clixml -Path .\file.xml
PS > $newcert = $inObject | Where-Object { $_.GetType().Name -like "*X509Certificate2" }
PS > $newcert.HasPrivateKey
false
I noted that there is a method for $cert.PrivateKey:
ExportParameters Method System.Security.Cryptography.RSAParameters ExportParameters(bool includePrivateParameters)
This script is not specifically running in Windows and the certificate isn't installed in the CABI store, only the variable imported from Get-PfxCertificate.
Long story short, I'm building a module that connects to an API with client authentication. I'm trying to pull client authentication from the Clixml file.
The private key is not a part of X509Certificate2 object, thus it is not exported along with the public certificate. The private key is linked to the public certificate.
In order to export a certificate with a private key, you have to serialize the certificate and private key object before passing it to Export-CliXml.
Use the X509Certificate2.Export(X509Content​Type, Secure​String) method to export the certificate with the associated private key to PFX (PKCS#12 container). The private key material is password-protected.
Use the X509Certificate2.Import(Byte[], Secure​String, X509Key​Storage​Flags) method to import the certificate and associated private key after calling the Import-CliXml cmdlet.
This is the only option you have. Also, be aware that this approach works only when the private key is exportable. If the private key is non-exportable, the Export method will fail.
By converting the certificate object to PFX format (as suggested by Crypt32) and saving my objects in a hash table I was able to successfully export and import the array and certificate with private key.
PS > $cert.HasPrivateKey
true
PS > $pfx = $cert.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx,'Pa$$w0rd')
PS > $outObject = #{
>> myArray = $array
>> myCert = $pfx
>> }
PS > Export-Clixml -InputObject $outObject -Path .\file.xml
PS > $inObject = Import-Clixml -Path .\file.xml
PS > $newCert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::New($inObject.myCert,'Pa$$w0rd')
PS > $newCert.HasPrivateKey
true