Import Self-Signed Intermediate SSL Certificates to a Windows MID Server Using PowerShell<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Issue Self-signed intermediate SSL certificates must be imported into a MID Server's Java keystore (cacerts) on a Windows Server host. Web browsers on the server are blocked from accessing the internet, preventing the standard method of exporting certificates through a browser. Symptoms The MID Server fails to establish a secure connection to the ServiceNow instance.MID Server logs display SSL handshake errors or certificate trust failures such as PKIX path building failed or unable to find valid certification path to requested target.Attempts to export certificates via a web browser are not possible due to internet access restrictions on the server. Facts The MID Server is running on Windows Server.The environment uses self-signed intermediate SSL certificates in the chain between the MID Server and the ServiceNow instance.All web browsers on the Windows Server are blocked from internet access.The MID Server may or may not use a web proxy, and the proxy may or may not require authentication credentials.PowerShell is available on the Windows Server and can establish outbound TCP/HTTPS connections (directly or through a proxy). Cause The MID Server's bundled Java Runtime Environment (JRE) does not trust self-signed or custom intermediate certificates by default. These certificates must be explicitly imported into the JRE's cacerts keystore. Because browsers on the server cannot reach the internet, the typical method of viewing and exporting the certificate chain from a browser is unavailable. An alternative method using PowerShell is required to retrieve and export the certificates. Solution Select the appropriate scenario below based on your MID Server's network configuration. Each scenario involves three steps: verifying the certificate chain, exporting the certificates to .crt files, and importing them into the MID Server's Java keystore. Important: Replace https://example.com with your ServiceNow instance URL in all commands. For proxy scenarios, replace http://proxy.company.com:8080 with the proxy address and port configured in the MID Server's config.xml. Note: After importing certificates, restart the MID Server service for changes to take effect. Scenario A: MID Server Without a Web Proxy Step 1 — Verify the Certificate Chain Open PowerShell on the MID Server host and run the following command to display all certificates in the chain, including subject, issuer, validity dates, and thumbprint: $uri=[uri]'https://example.com';$tcp=[Net.Sockets.TcpClient]::new($uri.DnsSafeHost,$uri.Port);$ssl=[Net.Security.SslStream]::new($tcp.GetStream(),$false,({$true}));$ssl.AuthenticateAsClient($uri.DnsSafeHost);$cert=[Security.Cryptography.X509Certificates.X509Certificate2]$ssl.RemoteCertificate;$chain=[Security.Cryptography.X509Certificates.X509Chain]::new();$null=$chain.Build($cert);$chain.ChainElements|%{$c=$_.Certificate;[pscustomobject]@{Subject=$c.Subject;Issuer=$c.Issuer;NotBefore=$c.NotBefore;NotAfter=$c.NotAfter;Thumbprint=$c.Thumbprint}};$ssl.Dispose();$tcp.Close() Review the output to confirm the self-signed intermediate certificates are present in the chain. Step 2 — Export Certificates to .crt Files Run the following command to export each certificate in the chain as a .crt file in the current working directory: $u=[uri]'https://example.com';$c=New-Object Net.Sockets.TcpClient($u.DnsSafeHost,$u.Port);$s=New-Object Net.Security.SslStream($c.GetStream(),$false,({$true}));$s.AuthenticateAsClient($u.DnsSafeHost);$leaf=New-Object Security.Cryptography.X509Certificates.X509Certificate2 $s.RemoteCertificate;$ch=New-Object Security.Cryptography.X509Certificates.X509Chain;[void]$ch.Build($leaf);0..($ch.ChainElements.Count-1)|%{$x=$ch.ChainElements[$_].Certificate;$cn=([regex]::Match($x.Subject,'(?:^|,\s*)CN\s*=\s*([^,]+)').Groups[1].Value.Trim());if(-not $cn){$cn=$x.GetNameInfo([Security.Cryptography.X509Certificates.X509NameType]::SimpleName,$false)};$safe=($cn -replace '[\\/:*?"<>|]','_' -replace '\s+','_').Trim(' ._');if(-not $safe){$safe="cert-$($_)"};$p=Join-Path $pwd ("{0}-{1}.crt" -f $safe,$x.Thumbprint.Substring(0,8));[IO.File]::WriteAllBytes($p,$x.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert))};$s.Dispose();$c.Close() Verify the .crt files were created in the current directory. Each file is named using the certificate's Common Name (CN) and a partial thumbprint. Step 3 — Import Certificates into the MID Server Keystore Open Windows Command Prompt as Administrator.Change directories to the MID Server's agent\jre\bin directory: cd "<MID Server install path>\agent\jre\bin" Run the following command for each .crt file to import it into the cacerts keystore: keytool -import -alias <certificate alias> -file "<full path to certificate.crt>" -keystore "<MID Server install path>\agent\jre\lib\security\cacerts" -storepass changeit When prompted, type yes to trust the certificate.Restart the MID Server service. Scenario B: MID Server Using a Web Proxy (No Authentication) Step 1 — Verify the Certificate Chain Open PowerShell on the MID Server host and run the following command: $url='https://example.com';$proxy='http://proxy.company.com:8080';[Net.ServicePointManager]::ServerCertificateValidationCallback={ $true };$req=[Net.HttpWebRequest]::Create($url);$req.Method='HEAD';$req.Proxy=New-Object Net.WebProxy($proxy,$true);$req.Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;try{$req.GetResponse()|Out-Null}catch{};$leaf=New-Object Security.Cryptography.X509Certificates.X509Certificate2 $req.ServicePoint.Certificate;$ch=New-Object Security.Cryptography.X509Certificates.X509Chain;[void]$ch.Build($leaf);$ch.ChainElements|%{$_.Certificate|Select Subject,Issuer,NotBefore,NotAfter,Thumbprint} Review the output to confirm the self-signed intermediate certificates are present in the chain. Step 2 — Export Certificates to .crt Files Run the following command to export each certificate in the chain as a .crt file: $url='https://example.com';$proxy='http://proxy.company.com:8080';[Net.ServicePointManager]::ServerCertificateValidationCallback={ $true };$req=[Net.HttpWebRequest]::Create($url);$req.Method='HEAD';$req.Proxy=New-Object Net.WebProxy($proxy,$true);$req.Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;try{$req.GetResponse()|Out-Null}catch{};$leaf=New-Object Security.Cryptography.X509Certificates.X509Certificate2 $req.ServicePoint.Certificate;$ch=New-Object Security.Cryptography.X509Certificates.X509Chain;[void]$ch.Build($leaf);$ch.ChainElements|%{$x=$_.Certificate;$cn=([regex]::Match($x.Subject,'(?:^|,\s*)CN\s*=\s*([^,]+)').Groups[1].Value.Trim());if(-not $cn){$cn=$x.GetNameInfo([Security.Cryptography.X509Certificates.X509NameType]::SimpleName,$false)};$safe=($cn -replace '[\\/:*?"<>|]','_' -replace '\s+','_').Trim(' ._');if(-not $safe){$safe='cert'};$file=Join-Path $pwd ("{0}-{1}.crt" -f $safe,$x.Thumbprint.Substring(0,8));[IO.File]::WriteAllBytes($file,$x.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert));$x|Select Subject,Issuer,NotBefore,NotAfter,Thumbprint};$req.Abort() Verify the .crt files were created in the current directory. Step 3 — Import Certificates into the MID Server Keystore Open Windows Command Prompt as Administrator.Change directories to the MID Server's agent\jre\bin directory: cd "<MID Server install path>\agent\jre\bin" Run the following command for each .crt file to import it into the cacerts keystore: keytool -import -alias <certificate alias> -file "<full path to certificate.crt>" -keystore "<MID Server install path>\agent\jre\lib\security\cacerts" -storepass changeit When prompted, type yes to trust the certificate.Restart the MID Server service. Scenario C: MID Server Using a Web Proxy with Authentication Step 1 — Verify the Certificate Chain Open PowerShell on the MID Server host and run the following command. A credential prompt will appear — enter the proxy authentication credentials: $url='https://example.com';$proxy='http://proxy.company.com:8080';$pc=Get-Credential -Message 'Proxy credentials';[Net.ServicePointManager]::ServerCertificateValidationCallback={ $true };$req=[Net.HttpWebRequest]::Create($url);$req.Method='HEAD';$req.Proxy=New-Object Net.WebProxy($proxy,$true);$req.Proxy.Credentials=$pc.GetNetworkCredential();try{$req.GetResponse()|Out-Null}catch{};$leaf=New-Object Security.Cryptography.X509Certificates.X509Certificate2 $req.ServicePoint.Certificate;$ch=New-Object Security.Cryptography.X509Certificates.X509Chain;[void]$ch.Build($leaf);$ch.ChainElements|%{$_.Certificate|Select Subject,Issuer,NotBefore,NotAfter,Thumbprint};$req.Abort() Review the output to confirm the self-signed intermediate certificates are present in the chain. Step 2 — Export Certificates to .crt Files Run the following command to export each certificate in the chain. Enter proxy credentials when prompted: $url='https://example.com';$proxy='http://proxy.company.com:8080';$pc=Get-Credential -Message 'Proxy credentials';[Net.ServicePointManager]::ServerCertificateValidationCallback={ $true };$req=[Net.HttpWebRequest]::Create($url);$req.Method='HEAD';$req.Proxy=New-Object Net.WebProxy($proxy,$true);$req.Proxy.Credentials=$pc.GetNetworkCredential();try{$req.GetResponse()|Out-Null}catch{};$leaf=New-Object Security.Cryptography.X509Certificates.X509Certificate2 $req.ServicePoint.Certificate;$ch=New-Object Security.Cryptography.X509Certificates.X509Chain;[void]$ch.Build($leaf);$ch.ChainElements|%{$x=$_.Certificate;$cn=([regex]::Match($x.Subject,'(?:^|,\s*)CN\s*=\s*([^,]+)').Groups[1].Value.Trim());if(-not $cn){$cn=$x.GetNameInfo([Security.Cryptography.X509Certificates.X509NameType]::SimpleName,$false)};$safe=($cn -replace '[\\/:*?"<>|]','_' -replace '\s+','_').Trim(' ._');if(-not $safe){$safe='cert'};$file=Join-Path $pwd ("{0}-{1}.crt" -f $safe,$x.Thumbprint.Substring(0,8));[IO.File]::WriteAllBytes($file,$x.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert));$x|Select Subject,Issuer,NotBefore,NotAfter,Thumbprint};$req.Abort() Verify the .crt files were created in the current directory. Step 3 — Import Certificates into the MID Server Keystore Open Windows Command Prompt as Administrator.Change directories to the MID Server's agent\jre\bin directory: cd "<MID Server install path>\agent\jre\bin" Run the following command for each .crt file to import it into the cacerts keystore: keytool -import -alias <certificate alias> -file "<full path to certificate.crt>" -keystore "<MID Server install path>\agent\jre\lib\security\cacerts" -storepass changeit When prompted, type yes to trust the certificate.Restart the MID Server service. Related Documentation ServiceNow MID Server SSL CertificatesJava Keytool Documentation