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 密码套件
(完)