Windows 系统 TLS 密码套件操作
一、前言
Windows 10 及 Windows Server 2016 操作系统可以使用 PowerShell 命令获得系统支持的 TLS 密码套件列表,并且禁用或启用相应的密码套件。其他版本 Windows 系统密码套件,微软没有给出 PowerShell 操作命令,但在微软给出了,使用 C++ 调用函数,和使用 Microsoft 管理控制台,操作密码套件。
二、获取密码套件列表
使用命令GET-TlsCipherSuite获取计算机的 TLS 密码套件列表。
语法:
Get-TlsCipherSuite [[-Name] <String>] [<CommonParameters>]
参数:
[[-Name] <String>]非必选参数。值为字符串类型,无默认值。指定要获取的 TLS 密码套件的名称。可指定部分名称,支持模糊匹配,不支持通配符匹配。[<CommonParameters>]非必选参数。固定参数:-Verbose、-Debug、-ErrorAction、-ErrorVariable、-OutBuffer和-OutVariable。
示例 1:获取所有密码套件
此命令获取计算机的所有 TLS 密码套件。
PS C:\> Get-TlsCipherSuite
示例 2:获取与字符串匹配的密码套件
此命令获取名称包含字符串 DES 的所有密码套件。
PS C:\> Get-TlsCipherSuite -Name "DES"
三、启用密码套件
使用命令Enable-TlsCipherSuite启用 TLS 密码套件。
语法:
Enable-TlsCipherSuite [-Name] <String> [[-Position] <UInt32>] [<CommonParameters>]
参数:
[-Name] <String>必选参数。指定要启用的 TLS 密码套件的名称。[[-Position] <UInt32>]非必选参数。指定在 TLS 密码套件的有序列表中插入密码套件的位置。如果不指定位置,则默认插入列表末尾。指定值 0 或CRYPT_PRIORITY_TOP以将插入列表顶部。指定值4294967295或0xFFFFFFFF或CRYPT_PRIORITY_BOTTOM以在列表末尾插入。[<CommonParameters>]非必选参数。固定参数:-Verbose、-Debug、-ErrorAction、-ErrorVariable、-OutBuffer和-OutVariable。
示例 1:启用密码套件
此命令启用名为TLS_DHE_DSS_WITH_AES_256_CBC_SHA的密码套件。此命令将密码套件 TLS 密码套件列表添加为最低优先级。
PS C:\> Enable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"
示例 2:启用密码套件作为最低优先级
此命令启用名为TLS_DHE_DSS_WITH_AES_256_CBC_SHA的密码套件。此命令将密码套件 TLS 密码套件列表添加为最低优先级。与第一个示例不同,此命令显式指定位置编号4294967295,它是CRYPT_PRIORITY_BOTTOM的值。
PS C:\> Enable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" -Position 4294967295
示例 3:启用密码套件作为最高优先级
此命令启用名为TLS_DHE_DSS_WITH_AES_256_CBC_SHA的密码套件。此命令将密码套件添加到位置 0 的 TLS 密码套件列表,这是最高优先级。
PS C:\> Enable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" -Position 0
四、禁用密码套件
使用命令Disable-TlsCipherSuite禁用 TLS 密码套件。
语法:
Disable-TlsCipherSuite [-Name] <String> [ <CommonParameters>]
参数:
[-Name] <String>必选参数。指定要禁用的 TLS 密码套件的名称。[<CommonParameters>]非必选参数。固定参数:-Verbose、-Debug、-ErrorAction、-ErrorVariable、-OutBuffer和-OutVariable。
示例 1:禁用密码套件
此命令禁用名为TLS_RSA_WITH_3DES_EDE_CBC_SHA的密码套件。该命令从 TLS 协议密码套件列表中删除密码套件。
PS C:\> Disable-TlsCipherSuite -Name "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
注意
如果禁用某个密码套件后,当你再次获取密码套件列表时Get-TlsCipherSuite,将不会出现在列表里,已禁用的密码套件也没有命令可以查询,你只能去查看微软文档,查看当前系统支持的密码套件列表,获取密码套件名称后,再次启用Enable-TlsCipherSuite -Name "密码套件全名"。微软文档链接:Cipher Suites in TLS/SSL (Schannel SSP)
五、其他版本 Windows 系统密码套件
在 Windows 10 和 Windows Server 2016 之前的版本系统中,微软没有给出 PowerShell 操作命令,但在微软文档中给出了,使用 C++ 调用函数,操作密码套件;如果感觉 C++ 麻烦也可以使用 Microsoft 管理控制台中的“组策略对象”管理单元配置 SSL Cipher Suite 订单组策略设置来修改密码套件列表。以上这些,都在微软文档中有提到,微软文档链接:Prioritizing Schannel Cipher Suites
另外,在 Stack Overflow 上有人问如何使用 C# 调用 Schannel 函数,操作密码套件。将微软文档中提到的,用 C++ 获取密码套件列表的代码,改成使用 C# 代码获取密码套件列表,并且成功了。Stack Overflow 链接:How to Call Schannel Functions from .Net/C#
C# 代码如下:
using System;using System.Text;using System.Runtime.InteropServices;namespace ConsoleApplication1{class Program{[DllImport("Bcrypt.dll", CharSet = CharSet.Unicode)]static extern uint BCryptEnumContextFunctions(uint dwTable, string pszContext, uint dwInterface, ref uint pcbBuffer, ref IntPtr ppBuffer);[DllImport("Bcrypt.dll")]static extern void BCryptFreeBuffer(IntPtr pvBuffer);[DllImport("Bcrypt.dll", CharSet = CharSet.Unicode)]static extern uint BCryptAddContextFunction(uint dwTable, string pszContext, uint dwInterface, string pszFunction, uint dwPosition);[DllImport("Bcrypt.dll", CharSet = CharSet.Unicode)]static extern uint BCryptRemoveContextFunction(uint dwTable, string pszContext, uint dwInterface, string pszFunction);[StructLayout(LayoutKind.Sequential)]public struct CRYPT_CONTEXT_FUNCTIONS{public uint cFunctions;public IntPtr rgpszFunctions;}const uint CRYPT_LOCAL = 0x00000001;const uint NCRYPT_SCHANNEL_INTERFACE = 0x00010002;const uint CRYPT_PRIORITY_TOP = 0x00000000;const uint CRYPT_PRIORITY_BOTTOM = 0xFFFFFFFF;public static void DoStuff(){uint cbBuffer = 0;IntPtr ppBuffer = IntPtr.Zero;uint Status = BCryptEnumContextFunctions(CRYPT_LOCAL,"SSL",NCRYPT_SCHANNEL_INTERFACE,ref cbBuffer,ref ppBuffer);if (Status == 0){CRYPT_CONTEXT_FUNCTIONS functions = (CRYPT_CONTEXT_FUNCTIONS)Marshal.PtrToStructure(ppBuffer, typeof(CRYPT_CONTEXT_FUNCTIONS));Console.WriteLine(functions.cFunctions);IntPtr pStr = functions.rgpszFunctions;for (int i = 0; i < functions.cFunctions; i++){Console.WriteLine(Marshal.PtrToStringUni(Marshal.ReadIntPtr(pStr)));pStr += IntPtr.Size;}BCryptFreeBuffer(ppBuffer);}}static void Main(string[] args){DoStuff();Console.ReadLine();}}}
六、参考文献
- 微软文档:获取 TLS 密码套件列表
- 微软文档:启用 TLS 密码套件
- 微软文档:禁用 TLS 密码套件
(完)