C# 解码活动目录 SID 第三位数字被错误解码。所有其他的正确



我从Active Directory检索一个objectsid值。它是一个base64编码的字符串。

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

下面的函数在除少数以外的所有情况下都能正常工作.在Active Directory属性编辑器中检查时,SID为"S-1-521 - 3477787073 - 812361429 - 3477787073,被返回为"S-1-421 - 3477787073 - 812361429 - 3477787073"。第三位数字差1

同样,SID为"S-1-532 - 573"返回为"S-1-2-32-573",第三位又少了3。

我已经调试了足够多,找出是byte[]数组的长度不同,我认为这是导致这个错误的原因。

当字节数组为28位时,解码正确。如果小于28位,则与byte[]数组的长度直接相关,第三个SID数字关闭。

我认为有一些关于for()循环条件i < bytes[7],即使byte[7]似乎总是5在所有情况下(至少那些我已经断点)。

或者可能是BitConverter的第二个参数(8 + (i * 4))。如果byte[7]总是5,那么(5*4)+ 8 = 28。当字节数组是28位时,返回值总是正确的。当byte[]数组小于28位时,返回值是错误的。

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

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

期望值:"S-1-521 - 3477787073 - 812361429 - 3477787073,

实际返回值:"S-1-4

21 - 3477787073 - 812361429 - 3477787073,你知道怎么解决这个问题吗?我是否需要将数组填充到28位,甚至32位?

正如评论中所指出的,SecurityIdentifier类使这很容易:

public static string Base64DecodeSID(string data) {
var bytes = Convert.FromBase64String(data);

var sid = new SecurityIdentifier(bytes, 0);

return sid.Value;
}

你可能想在那里添加一些错误检查,以防它传递了一个坏值。

调用Base64DecodeSID("AQQAAAAAAAUVAAAAwdFKz9WmazDFb3Y8")返回S-1-5-21-3477787073-812361429-1014394821

相关内容

最新更新