| Nedávno jsem tu uveřejňoval skript na vytváření a případně tedy i testování HTTP spojení pomocí jazyka PowerShell. Tak dneska zde mám skript na testování TLS (nebo jak se tomu v pravěku říkalo - SSL) spojení. To je takové to šifrování komunikace, které se používá pro zabezpečení protokolů, jako je HTTPS, LDAPS, RDP, SMTPS, pokud by někdo nevěděl.
TLS znamená Transport Layer Security a máte ho od Windows 7 a Windows 2008 R2 k dispozici ve verzích TLS 1.0, TLS 1.1 a TLS 1.2 (a navíc ještě jako DTLS, ale to je už jiná pohádka). Jedná se o to, že se nejprve ustaví TCP spojení na nějaký serverovský port (například právě 443 pro HTTPS, nebo 636 pro LDAPS). Na tomto TCP spojení se domluví TLS šifrování. A teprve až je ustaveno TLS šifrování, tak se teprve posílají vůbec aplikační data, jako je třeba právě HTTP GET, nebo HTTP POST a nebo SMTP EHLO.
To znamená, že testovat TLS spojení je možné na libovolném TCP portu, bez ohledu na to, jaká aplikace tam pracuje a jaká má svoje vlastní specifika. Uděláme TCP spojení a prostě ustavíme TLS. Tohle musí samo od sebe fungovat. Pokud tohle neprojde, ani pozdější aplikační komunikace by stejně nefungovala.
Takže juchů na to. Konkrétní algoritmy ani suitu si explicitně nevyberete, to se musí udělat pomocí registrových hodnot (o tom zase příště), ale můžete si zvolit algoritmus a můžete také zvolit, jestli se povoluje, nebo vyžaduje NULL šifrování - tzn. bez šifrování - zakázat což je jedno ze základních bezpečnostních nastavení.
Používám SslStream a rovnou jsem to umístil do funkce.
function global:Test-TLS (
[string] $hostName,
[int] $port = 443,
[string] $clientCertThumbprint = $null,
[System.Net.Security.EncryptionPolicy] $encryption = [System.Net.Security.EncryptionPolicy]::AllowNoEncryption,
[bool] $chechRevocation = $false,
[System.Security.Authentication.SslProtocols] $sslProtocol = [System.Security.Authentication.SslProtocols]::Default
)
{
# [System.Net.Security.EncryptionPolicy]
# AllowNoEncryption
# NoEncryption
# RequireEncryption
# [System.Net.Security.SslProtocols]
# Default
# None
# Ssl2
# Ssl3
# Tls
# Tls11
# Tls12
[bool] $result = $false
echo ('Going to connect to: {0} | {1}' -f $hostName, $port)
[System.Net.Sockets.TcpClient] $client = New-Object System.Net.Sockets.TcpClient $hostName, $port
if ($client -ne $null) {
echo ('Initialize SslStream object with encryption level: {0}' -f $encryption)
[System.IO.Stream] $netStream = $client.GetStream()
[System.Net.Security.SslStream] $sslStream = New-Object System.Net.Security.SslStream $netStream, $false, $null, $null, $encryption
if ($sslStream -ne $null) {
$clientCert = $null
if ($clientCertThumbprint -ne '') {
echo ('Open the client certificate with thumbprint: {0}' -f $clientCertThumbprint)
$clientCert = Get-Item "Cert:\CurrentUser\My\$clientCertThumbprint"
}
echo ('Start SSL session: {0} | {1} | {2} | {3}' -f $hostName, $chechRevocation, $clientCert.Subject, $clientCert.Issuer)
$sslStream.AuthenticateAsClient($hostName, $clientCert, $sslProtocol, $chechRevocation)
if ($sslStream.IsAuthenticated) {
$result = $true
echo ('Protocol: {0}' -f $sslStream.SslProtocol)
echo ('Cipher: {0} | {1}' -f $sslStream.CipherAlgorithm, $sslStream.CipherStrength)
echo ('Hash: {0} | {1}' -f $sslStream.HashAlgorithm, $sslStream.HashStrength)
echo ('Key exchange: {0} | {1}' -f $sslStream.KeyExchangeAlgorithm, $sslStream.KeyExchangeStrength)
$sCer = $sslStream.RemoteCertificate
if ($sCer -ne $null) {
echo ('Server certificate thumbprint: {0}' -f $sCer.GetCertHashString())
echo ('Server certificate subject: {0}' -f $sCer.Subject)
echo ('Server certificate issuer: {0}' -f $sCer.Issuer)
echo ('Server certificate not after: {0:s}' -f [DateTime]::Parse($sCer.GetExpirationDateString()))
echo ('Server certificate not before: {0:s}' -f [DateTime]::Parse($sCer.GetEffectiveDateString()))
} else {
echo ('Server certificate: None')
}
} else {
$result = $false
echo ('Error authenticating to the server')
}
echo ('Close TLS session.')
$sslStream.Dispose()
$netStream.Dispose()
}
echo ('Close TCP connection.')
$client.Dispose()
}
return $result
}
Když to chcete otestovat, můžete buď použít jednoduše Show-Command Test-Tls, nebo rovnou z příkazové řádky zadat následující:
Test-TLS -encryption AllowNoEncryption -hostName sss.google.com -chechRevocation $True -port 443 -sslProtocol Tls12
Tak pěkný nový rok! |