I'm building Active Directory Authentication into my application and I am planning to link my application's internal accounts to a user's domain SID. It is easier for me to work with the string format of the sid than a byte array so I was planning to store it in the database as a string. How long should I make the field to ensure SID's will not get truncated?
I had the same question, and I believe the right answer is:
- ID as string: 184 characters, or varchar(184) in SQL Server
- SID as string of Hex digits: 136 characters, or varchar(136) in SQL Server
- SID as binary: 68 bytes, or varbinary(68) in SQL Server
I haven't checked the math myself, but the technique used here looks valid: https://groups.google.com/d/msg/microsoft.public.dotnet.security/NpIi7c2Toi8/31SVhcepY58J
Refer to the program written by Russell Mangel on Aug 19, 2006, also copied here for reference:
So the answer to my question is:
varbinary(68)-- pure binary
varchar(136) -- (68*2) = hexString
varchar(184) -- SID StringI wrote a little program to test, notice that .NET 2.0 has SecurityIdentifier.MaxBinaryLength, I didn't know about this.
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);
Results
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
According to 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)
A UCHAR is actually an unsigned char which is 1 byte. ULONG is an unsigned long which is 4 bytes.
SID's max data size is 68 bytes: UCHAR + UCHAR + (UCHAR * 6) + (ULONG * 15) = 1 + 1 + 6 + 60 = 68
Converting a SID to a string, like what you would get by calling ConvertSidToStringSid, might look something like this: L"S-1-5-21-66"
- "S-1" <= is the start of all SIDs
- 3 characters
- "5" <= is the identifier authority
- the numbers are printed as decimals normally. One exception is if the authority is larger 4 bytes, then it is printed as hex, eg. 0x1234...
- So the max value would be "4294967296" or "0xffffffffffff" or 14 characters
- "21" & "66" <= are sub-authrities
- Each can be up "4294967296" or 10 characters, with 15 max sub authorities
- the sections are delimited by a "-"
SID's max string length is 184: 3 + 1 + 14 + 1 + (10 * 15) + 14 = 183, or 184 counting the null.
You may consider just using MAX_UNICODE_STACK_BUFFER_LENGTH or 256 which fits nicely in memory.
- For string format, the common answer of 184 isn't correct. If authority is between 32 and the maximum of 48 bits, then it must be represented as a hex string, not decimal, and prepended with '0x'. This means instead of a 15-character string needed to represent the maximum 48 bits in decimal, you actually need a (48 bit / 4 bit + 2) 14 character string, meaning (184 - 15 + 14) 183 characters are required for whole SID string. For less than 32 bits, decimal format is used (maximum 10 decimal characters).
While 184 looks correct, on the official docs there is a different value:
SID - Specifies the security identifier of the domain account. SID is a string with a maximum length of 256 characters.
© 2022 - 2024 — McMap. All rights reserved.