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
我从 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