VMware Cloud Community
lamw
Community Manager
Community Manager
Jump to solution

Extracting SSL Thumbprint from initial Connect-VIServer

Sorry if this has already been asked before, but I've not been able to find this by searching online or in the forums.

When you initially make a connection to either a VC/ESXi host, there's some information displayed about x509 Certificate as seen below.

* The X509 chain could not be built up to the root certificate.

Certificate: [Subject]

  C=US, CN=vcenter60-4.primp-industries.com

[Issuer]

  O=vcenter60-4.primp-industries.com, C=US, DC=local, DC=vghetto, CN=CA

[Serial Number]

  00D9B9AE28CFD6CF4D

[Not Before]

  2/8/2015 9:19:14 AM

[Not After]

  2/2/2025 9:19:13 AM

[Thumbprint]

  B846B9F36C1D978CEDA0199294E61B4515656396

I would like to capture the SSL Thumbprint "B846B9F36C1D978CEDA0199294E61B4515656396"? I've looked online and even asked some folks but never been able to retrieve this property using PowerShell/PowerCLI. I can easily do this on a non-Windows system with openssl (http://www.virtuallyghetto.com/2012/04/extracting-ssl-thumbprint-from-esxi.html) but wanted to see if there's a way without having to relay on external packages and since it's available as part of the Connect-VIServer, I figured it must be possible but my PowerCLI-Fu is not quite up to par as others, so figure I ask. If this is indeed extractable, which I assume it is then a bonus would be to format it so I have a variable that looks like: B8:46:B9:F3:6C:1D:97:8C:ED:A0:19:92:94:E6:1B:45:15:65:63:96


Thanks Luc in advance Smiley Wink

Tags (2)
1 Solution

Accepted Solutions
alanrenouf
VMware Employee
VMware Employee
Jump to solution

Function Test-WebServerSSL {

# Function original location: http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?List=332991f0-bfed-4143-9eea-f521167d287c&ID=60

[CmdletBinding()]

    param(

        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]

        [string]$URL,

        [Parameter(Position = 1)]

        [ValidateRange(1,65535)]

        [int]$Port = 443,

        [Parameter(Position = 2)]

        [Net.WebProxy]$Proxy,

        [Parameter(Position = 3)]

        [int]$Timeout = 15000,

        [switch]$UseUserContext

    )

Add-Type @"

using System;

using System.Net;

using System.Security.Cryptography.X509Certificates;

namespace PKI {

    namespace Web {

        public class WebSSL {

            public Uri OriginalURi;

            public Uri ReturnedURi;

            public X509Certificate2 Certificate;

            //public X500DistinguishedName Issuer;

            //public X500DistinguishedName Subject;

            public string Issuer;

            public string Subject;

            public string[] SubjectAlternativeNames;

            public bool CertificateIsValid;

            //public X509ChainStatus[] ErrorInformation;

            public string[] ErrorInformation;

            public HttpWebResponse Response;

        }

    }

}

"@

    $ConnectString = "https://$url`:$port"

    $WebRequest = [Net.WebRequest]::Create($ConnectString)

    $WebRequest.Proxy = $Proxy

    $WebRequest.Credentials = $null

    $WebRequest.Timeout = $Timeout

    $WebRequest.AllowAutoRedirect = $true

    [Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

    try {$Response = $WebRequest.GetResponse()}

    catch {}

    if ($WebRequest.ServicePoint.Certificate -ne $null) {

        $Cert = [Security.Cryptography.X509Certificates.X509Certificate2]$WebRequest.ServicePoint.Certificate.Handle

        try {$SAN = ($Cert.Extensions | Where-Object {$_.Oid.Value -eq "2.5.29.17"}).Format(0) -split ", "}

        catch {$SAN = $null}

        $chain = New-Object Security.Cryptography.X509Certificates.X509Chain -ArgumentList (!$UseUserContext)

        [void]$chain.ChainPolicy.ApplicationPolicy.Add("1.3.6.1.5.5.7.3.1")

        $Status = $chain.Build($Cert)

        New-Object PKI.Web.WebSSL -Property @{

            OriginalUri = $ConnectString;

            ReturnedUri = $Response.ResponseUri;

            Certificate = $WebRequest.ServicePoint.Certificate;

            Issuer = $WebRequest.ServicePoint.Certificate.Issuer;

            Subject = $WebRequest.ServicePoint.Certificate.Subject;

            SubjectAlternativeNames = $SAN;

            CertificateIsValid = $Status;

            Response = $Response;

            ErrorInformation = $chain.ChainStatus | ForEach-Object {$_.Status}

        }

        $chain.Reset()

        [Net.ServicePointManager]::ServerCertificateValidationCallback = $null

    } else {

        Write-Error $Error[0]

    }

}

$cert = Test-WebServerSSL MYVC

$cert.Certificate.Thumbprint

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com

View solution in original post

Reply
0 Kudos
16 Replies
LucD
Leadership
Leadership
Jump to solution

Hi William,

Try like this

$vcenter = 'vcenter'

$user = 'account'

$pswd = 'password'

Connect-VIServer -Server $vcenter -User $user -Password $pswd | Out-Null

$thumbprint = Get-ChildItem -Recurse -Path cert: | where {$_.Subject -match $vcenter} | select -ExpandProperty Thumbprint

($thumbprint -split '(..)' | where {$_}) -join ':'


Don't you just love PowerCLI Smiley Wink


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

lamw
Community Manager
Community Manager
Jump to solution

Luc,

Is there other way to generate the SHA1 Fingerprint? I just noticed that this info is only displayed on initial connection, it's not shown again after the fact. Thanks

I would have thought it would be shorter one-liner like the following? Smiley Wink

echo -n | openssl s_client -connect 172.30.0.252:443 2>/dev/null | openssl x509 -noout -fingerprint -sha1

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You want an unreadable one-liner, here you go :smileygrin:

dir -r cert: | ? Subject -ma $vcenter | Select -exp Thumbprint

The Thumbprint is indeed only shown at the first Connect-VIServer in a PowerShell session.

In fact, it is stored in the Cert repository, you don't even need to do a Connect-VIServer.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

alanrenouf
VMware Employee
VMware Employee
Jump to solution

Function Test-WebServerSSL {

# Function original location: http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?List=332991f0-bfed-4143-9eea-f521167d287c&ID=60

[CmdletBinding()]

    param(

        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]

        [string]$URL,

        [Parameter(Position = 1)]

        [ValidateRange(1,65535)]

        [int]$Port = 443,

        [Parameter(Position = 2)]

        [Net.WebProxy]$Proxy,

        [Parameter(Position = 3)]

        [int]$Timeout = 15000,

        [switch]$UseUserContext

    )

Add-Type @"

using System;

using System.Net;

using System.Security.Cryptography.X509Certificates;

namespace PKI {

    namespace Web {

        public class WebSSL {

            public Uri OriginalURi;

            public Uri ReturnedURi;

            public X509Certificate2 Certificate;

            //public X500DistinguishedName Issuer;

            //public X500DistinguishedName Subject;

            public string Issuer;

            public string Subject;

            public string[] SubjectAlternativeNames;

            public bool CertificateIsValid;

            //public X509ChainStatus[] ErrorInformation;

            public string[] ErrorInformation;

            public HttpWebResponse Response;

        }

    }

}

"@

    $ConnectString = "https://$url`:$port"

    $WebRequest = [Net.WebRequest]::Create($ConnectString)

    $WebRequest.Proxy = $Proxy

    $WebRequest.Credentials = $null

    $WebRequest.Timeout = $Timeout

    $WebRequest.AllowAutoRedirect = $true

    [Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

    try {$Response = $WebRequest.GetResponse()}

    catch {}

    if ($WebRequest.ServicePoint.Certificate -ne $null) {

        $Cert = [Security.Cryptography.X509Certificates.X509Certificate2]$WebRequest.ServicePoint.Certificate.Handle

        try {$SAN = ($Cert.Extensions | Where-Object {$_.Oid.Value -eq "2.5.29.17"}).Format(0) -split ", "}

        catch {$SAN = $null}

        $chain = New-Object Security.Cryptography.X509Certificates.X509Chain -ArgumentList (!$UseUserContext)

        [void]$chain.ChainPolicy.ApplicationPolicy.Add("1.3.6.1.5.5.7.3.1")

        $Status = $chain.Build($Cert)

        New-Object PKI.Web.WebSSL -Property @{

            OriginalUri = $ConnectString;

            ReturnedUri = $Response.ResponseUri;

            Certificate = $WebRequest.ServicePoint.Certificate;

            Issuer = $WebRequest.ServicePoint.Certificate.Issuer;

            Subject = $WebRequest.ServicePoint.Certificate.Subject;

            SubjectAlternativeNames = $SAN;

            CertificateIsValid = $Status;

            Response = $Response;

            ErrorInformation = $chain.ChainStatus | ForEach-Object {$_.Status}

        }

        $chain.Reset()

        [Net.ServicePointManager]::ServerCertificateValidationCallback = $null

    } else {

        Write-Error $Error[0]

    }

}

$cert = Test-WebServerSSL MYVC

$cert.Certificate.Thumbprint

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
Reply
0 Kudos
lamw
Community Manager
Community Manager
Jump to solution

I prefer not to rely on cached content as it can change. The one-liner using OpenSSL is simple enough to make a quick connect, but was hoping there was an equivalent in PowerShell or easier way via PowerCLI if we had that info. I guess Alan's reply confirmed my suspicion that retrieving this particular property is not as easy as I had hoped. I'll just use use Alan's method for now and have already asked for an enhancement to PowerCLI Smiley Happy

Thanks again for your assistance Luc, good to known about these other methods and hopefully this can help others with similar requests

Reply
0 Kudos
alanrenouf
VMware Employee
VMware Employee
Jump to solution

Feature request added Smiley Happy

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
kunaludapi
Expert
Expert
Jump to solution

I tried below on couple of my servers it worked for me, I had to to make sure your powercli ignoresettings are set to unset.

$test = Powershell -Command  "Add-PSSnapin vmware.vimautomation.core; Connect-VIServer esxi -User Username -Password Password"

$test[46].trim()

for vcenter i found thumbprint comes on 44 line. and for esxi it comes on 46. I could be on different line for you environment.

--------------------------------------------------------------- Kunal Udapi Sr. System Architect (Virtualization, Networking And Storage) http://vcloud-lab.com http://kunaludapi.blogspot.com VMWare vExpert 2014, 2015, 2016 If you found this or other information useful, please consider awarding points for "Correct" or "Helpful".
Reply
0 Kudos
nram1983
Contributor
Contributor
Jump to solution

This function worked fine till I was using comodo ssl certificate. Now I started using entrust ssl certificates and its throwing the exception "An error occured retrieving the SSL certificate".

Any help here would be really appreciatred.

Regards

Ramakrishnan

Reply
0 Kudos
ehsanijavad
Enthusiast
Enthusiast
Jump to solution

Hi LucD,

Could you tell me, How can I find these information of ESXi Hosts (Powercli).

pastedImage_0.png

Thank you for your answer.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

In fact the same way as for a vCenter.
Just use the ESXi Uri.

William wrote a function for this Get-SSLThumprint.

Instead of the thumbprint, you can also retrieve the Issuer, the Subject and many other properties.

What exactly do you want?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ehsanijavad
Enthusiast
Enthusiast
Jump to solution

Thank you so much LucD,

I want these informations:

     serial number:

    Signature algorithm:

     issuer:

     valid from:

     valid to:

     subject:

Reply
0 Kudos
ehsanijavad
Enthusiast
Enthusiast
Jump to solution

Hi LucD

Thank you for your help.

I have tried to find these information, but I can't.

SHA.JPG

Could you please help me?

Thank you.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you use Alan's code from earlier in this thread, the information is in $cert.Certificate.SignatureAlgorithm.FriendlyName


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ehsanijavad
Enthusiast
Enthusiast
Jump to solution

Hi LucD

Thank you for your answer, your mean:

[System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy

    # Need to connect using simple GET operation for this to work

    Invoke-RestMethod -Uri $URL -Method Get | Out-Null

    $ENDPOINT_REQUEST = [System.Net.Webrequest]::Create("$URL")

    $SSL_THUMBPRINT = $ENDPOINT_REQUEST.ServicePoint.Certificate.GetCertHashString()

   $FriendlyName = $ENDPOINT_REQUEST.ServicePoint.Certificate.signatureAlgorithm.FriendlyName

    return $SSL_THUMBPRINT -replace '(..(?!$))','$1:'

    $FriendlyName

But it doesn't work for me.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I mean Alan's Test-WebServerSSL function.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ehsanijavad
Enthusiast
Enthusiast
Jump to solution

Hi LucD

Thank you for your support.

It doesn't work for me.

Do you have any other idea?

Thank you.

Reply
0 Kudos