我正在将 Active Directory 身份验证构建到我的应用程序中,并且我计划将我的应用程序的内部帐户链接到用户的域 SID。对我来说,使用 sid 的字符串格式比使用字节数组更容易,所以我打算将它作为字符串存储在数据库中。我应该填写多长时间以确保 SID 不会被截断?
4 回答
我有同样的问题,我相信正确的答案是:
- 字符串形式的 ID:184 个字符,或 SQL Server 中的 varchar(184)
- SID 作为十六进制数字字符串:136 个字符,或 SQL Server 中的 varchar(136)
- SID 作为二进制:68 字节,或 SQL Server 中的 varbinary(68)
我自己没有检查过数学,但这里使用的技术看起来是有效的: https ://groups.google.com/d/msg/microsoft.public.dotnet.security/NpIi7c2Toi8/31SVhcepY58J
参考 Russell Mangel 在 2006 年 8 月 19 日编写的程序,也复制到这里以供参考:
所以我的问题的答案是:
varbinary(68)-- 纯二进制
varchar(136) -- (68*2) = hexString
varchar(184) -- SID String我写了一个小程序来测试,注意到 .NET 2.0 有 SecurityIdentifier.MaxBinaryLength,我不知道这个。
Console.WriteLine("SID Min. num Bytes: {0}", SecurityIdentifier.MinBinaryLength); Console.WriteLine("SID Max. num Bytes: {0}", SecurityIdentifier.MaxBinaryLength); Byte[] bytes = new byte[SecurityIdentifier.MaxBinaryLength]; for (Int32 i = 0; i < bytes.Length; i++) { bytes[i] = 0xFF; } bytes[0] = 0x01; // Must be 1 bytes[1] = 0x0F; // Max 15 (base10) SecurityIdentifier sid = new SecurityIdentifier(bytes, 0); String sidString = sid.ToString(); Console.WriteLine("Max length of SID in String format: {0} ", sidString.Length); Console.WriteLine(sidString);
结果
SID Min. num Bytes: 8 SID Max. num Bytes: 68 Max length of SID in String format: 184 S-1-281474976710655-4294967295-4294967295-4294967295-4294967295-4294967295- 4294967295-4294967295-4294967295-4294967295-4294967295-4294967295- 4294967295-4294967295-4294967295-4294967295
- 对于字符串格式,184 的常见答案是不正确的。如果权限介于 32 位和最大 48 位之间,则它必须表示为十六进制字符串,而不是十进制,并以 '0x' 开头。这意味着您实际上需要一个(48 位 / 4 位 + 2)14 个字符的字符串,而不是一个 15 个字符的字符串来表示十进制的最大 48 位,这意味着整个需要(184 - 15 + 14)个 183 个字符SID 字符串。对于小于 32 位,使用十进制格式(最多 10 个十进制字符)。
根据ntseapi_x.h:
typedef struct _SID_IDENTIFIER_AUTHORITY {
UCHAR Value[6];
} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
typedef struct _SID {
UCHAR Revision;
UCHAR SubAuthorityCount;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
ULONG SubAuthority[ANYSIZE_ARRAY];
} SID, *PISID;
#define SID_MAX_SUB_AUTHORITIES (15)
UCHAR实际上是一个无符号字符,它是 1 个字节。 ULONG是一个无符号长整数,为 4 个字节。
SID 的最大数据大小为 68 字节:UCHAR + UCHAR + (UCHAR * 6) + (ULONG * 15) = 1 + 1 + 6 + 60 = 68
将 SID 转换为字符串,就像调用ConvertSidToStringSid得到的一样,可能看起来像这样:L"S-1-5-21-66"
- "S-1" <= 是所有 SID 的开始
- 3 个字符
- "5" <= 是标识符权威
- 这些数字通常以小数形式打印。一个例外是,如果权限大于 4 个字节,则将其打印为十六进制,例如。0x1234...
- 所以最大值将是“4294967296”或“0xffffffffffff”或14个字符
- "21" & "66" <= 是子权限
- 每个最多可以是“4294967296”或 10 个字符,最多 15 个子权限
- 这些部分由“-”分隔
SID 的最大字符串长度为 184:3 + 1 + 14 + 1 + (10 * 15) + 14 = 183,或 184 计算空值。
您可以考虑只使用 MAX_UNICODE_STACK_BUFFER_LENGTH 或 256 ,它非常适合内存。
虽然 184 看起来是正确的,但在官方文档中有一个不同的值:
SID - 指定域帐户的安全标识符。SID 是一个最大长度为 256 个字符的字符串。