# Windows TLS hardening: Schannel, cipher suites and safe rollback

> Harden IIS/Nginx TLS on Windows with TLS 1.2/1.3, deliberate cipher suites, a registry backup and client testing before disabling old protocols.

**Tested on**

- Build: 26100.33650
- Edition: Standard / Datacenter
- Architecture: x64
- Evidence: E1
- Verified: 2026-10-29

## The short answer

Windows TLS is **Schannel**; IIS/HTTP.sys and many services use it. Harden deliberately:

1. Inventory clients and protocols.
2. Enable TLS 1.2/1.3; disable TLS 1.0/1.1 only after client testing.
3. Remove known-weak cipher suites; prefer ECDHE + AES-GCM/ChaCha20.
4. Back up the registry before changes.
5. Test with `openssl s_client` and a real client matrix.

Do not paste a random “perfect TLS” registry file into production.

## Check what is offered

```powershell
Get-TlsCipherSuite | Select-Object Name,Protocol
openssl s_client -connect lab.example:443 -servername lab.example -tls1_2
openssl s_client -connect lab.example:443 -servername lab.example -tls1_3
```

`openssl` output shows the negotiated protocol/cipher. For an external view, use a TLS scanner; do not rely only on a browser padlock.

## Protocols

Registry paths (machine policy):

```text
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server
```

Typical hardening: `Enabled=0`, `DisabledByDefault=1` for old protocols; `Enabled=1`, `DisabledByDefault=0` for 1.2/1.3. A reboot is usually required for Schannel changes.

Back up first:

```powershell
reg export "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL" C:\backup\schannel.reg
```

## Cipher suites

```powershell
Get-TlsCipherSuite | Sort-Object Name
Disable-TlsCipherSuite -Name 'TLS_RSA_WITH_3DES_EDE_CBC_SHA'
```

Prefer ECDHE + AES-GCM/ChaCha20. Do not disable every CBC suite if a legacy client still needs one; document the exception. Cipher order can matter for older clients.

## IIS and Nginx

- IIS uses Schannel; the site binding only chooses the certificate.
- Nginx uses OpenSSL, not Schannel. Windows Nginx TLS is governed by `ssl_protocols`/`ssl_ciphers`, not the registry.
- If IIS and Nginx share a host, harden both separately.

> **Caution: TLS changes can lock out management**
>
> Disabling a protocol can break old RDP/management tools, line-of-business clients or monitoring. Keep an out-of-band console and a registry rollback file.

## Verify before and after

```powershell
# before
openssl s_client -connect lab.example:443 -servername lab.example -tls1_2 </dev/null
# after
curl.exe -I https://lab.example/
```

Test at least: current Chrome/Edge, a mobile client, an API client, and any legacy device you must support.

## Lab boundary

E1. The lab used a self-signed certificate for WAC and did not change Schannel. The registry/cipher steps are the hardening plan to validate on Server 2025.

## Sources

- [Microsoft Learn — TLS registry settings](https://learn.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings)
- [Microsoft Learn — Schannel](https://learn.microsoft.com/en-us/windows/win32/secauthn/schannel-credentials)

---

Source: https://windows.homes/en/server/tls/schannel/
