C# 解码 Active Directory SID 第三位数字解码不正确。其他都对

C# Decoding Active Directory SID third digit being decoded incorrectly. All other's correct

我从 Active Directory 中检索了一个 objectsid 值。它以 base64 编码的字符串形式出现。

我有以下函数(如下)将其解码为实际的 SID 文本字符串。

以下函数在所有情况下都能正常工作除了少数

在 Active Directory 属性编辑器中检查时,正在 returned 一个 SID“S-1-5-21-3477787073-812361429-1014394821”而不是“S-1-4-21-3477787073-812361429-1014394821”。第三位差一位。

同样,“S-1-5-32-573”的 SID 被 return编辑为“S-1- 2-32-573", 第三个数字又少了 3.

我已经对其进行了足够的调试,发现是 byte[] 数组的长度不同,我认为这是导致此错误的原因。

字节数组为28位时,解码正确。如果它短于 28 位,则第三个 SID 数字直接相对于 byte[] 数组短多少。

我认为 for() 循环条件 i < bytes[7] 有一些问题,尽管 byte[7] 在所有情况下似乎总是 5(至少我有断点)。

或者可能是 BitConverter 的第二个参数 (8 + (i * 4))。如果byte[7]始终为5,则(5*4)+8=28。而当字节数组为28位时,return的值始终正确。当byte[]数组小于28位时,return值是错误的。

我没有写这个函数(在另一个堆栈溢出问题的答案中找到),所以除了我在这里描述的内容之外,我真的不明白它在做什么。我确实添加了代码注释。

public static string Base64DecodeSID(string data) {

if (data == "") {
    return "";
}

byte[] bytes = Convert.FromBase64String(data);

try {

    string sid = "S-" + bytes[0].ToString();                                        // Add SID revision.

    if (bytes[6] != 0 || bytes[5] != 0) {                                           // SID authority

        sid += ("-" +
            String.Format(                                                          // Left 0-pad hex
                "0x{0:2x}{1:2x}{2:2x}{3:2x}{4:2x}{5:2x}",                           // values to 2 places.
                bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6]
            )
        );

    } else {
        sid += ("-" + (bytes[1] + (bytes[2] << 8) + (bytes[3] << 16) + (bytes[4] << 24)).ToString());
    }

    for (int i = 0; i < bytes[7]; i++) {                                            // Sub-Authority...
        sid += ("-" + BitConverter.ToUInt32(bytes, 8 + (i * 4)).ToString()); 
        
    }

    return sid;

}

(为简洁起见,我排除了 catch())

例子

Base64: "AQQAAAAAAAUVAAAAwdFKz9WmazDFb3Y8"

解码字节[]数组:

[00] 1
[01] 4
[02] 0
[03] 0
[04] 0
[05] 0
[06] 0
[07] 5
[08] 21
[09] 0
[10] 0
[11] 0
[12] 193
[13] 209
[14] 74
[15] 207
[16] 213
[17] 166
[18] 107
[19] 48
[20] 197
[21] 111
[22] 118
[23] 60

预期return值:“S-1-5-21-3477787073-812361429-1014394821”

实际return值:“S-1-4-21-3477787073-812361429-1014394821”

知道如何解决这个问题吗?我是否需要将数组填充到 28 位甚至 32 位?

如评论中所述,SecurityIdentifier class 使这变得简单:

public static string Base64DecodeSID(string data) {

    var bytes = Convert.FromBase64String(data);
    
    var sid = new SecurityIdentifier(bytes, 0);
    
    return sid.Value;
}

您可能想在其中添加一些错误检查,以防它传递了错误的值。

呼叫 Base64DecodeSID("AQQAAAAAAAUVAAAAwdFKz9WmazDFb3Y8") returns S-1-5-21-3477787073-812361429-1014394821