我们在尝试在集成服务器上自动注册密钥时遇到了这个问题。必须运行 Visual Studio 或 MSBuild 来提取 VS_KEY 是不可接受的。然后通过最详细地调查 MSBuild 日志,我发现了以下内容。
此密钥是通过 Microsoft.Build.Tasks.v4.0.dll(存在于 GAC 中)生成的。该 DLL 中有一个名为“ResolveKeySource”的类。通过使用 ILSpy 或 Reflector 查看代码,您将看到一个调用 ResolveAssemblyKey 的 Execute 方法。这个方法是 VS_KEY_xxxxxx 之谜的核心。
VS_KEY_xxxxx 值是通过将密钥内容与Environment.UserDomainName 和Environment.UserName 进行哈希运算而生成的。
第一个解决方案:您创建一个 ResolveKeySource 实例并调用适当的方法。由于您不提供密码和其他信息,它将引发一个异常,其消息包含强大的 VS_KEY 内容。
var key = new ResolveKeySource();
key.KeyFile = path_to_key_file;
try {
key.Execute();
} catch (Exception e) {
var match = Regex.Match(e.Message, "VS_KEY_[A-F0-9]+");
if (match.Success) {
return match.Value;
}
}
第二种解决方案:获取生成此哈希码的代码并使用它直接获取值,没有异常。这或多或少是 DLL 的摘录。
public static string GetLocalUserKeyContainerByGeneration(string keyFile) {
string localName = Environment.UserDomainName + "\\" + Environment.UserName;
FileStream keyFileStream = null;
try {
keyFileStream = File.OpenRead(keyFile);
int num = (int)keyFileStream.Length;
byte[] array = new byte[num];
keyFileStream.Read(array, 0, num);
ulong hash1 = HashFromBlob(array);
byte[] bytes = Encoding.Unicode.GetBytes(localName.ToLower(CultureInfo.InvariantCulture));
return "VS_KEY_" + (hash1 ^ HashFromBlob(bytes)).ToString("X016", CultureInfo.InvariantCulture);
}
finally {
if (keyFileStream != null) {
keyFileStream.Close();
}
}
}
private static ulong HashFromBlob(byte[] data) {
uint num = 17339221u;
uint num2 = 19619429u;
uint num3 = 10803503u;
for (int i = 0; i < data.Length; i++) {
byte b = data[i];
uint num4 = (uint)b ^ num3;
num3 *= 10803503u;
num += (num4 ^ num2) * 15816943u + 17368321u;
num2 ^= ((num4 + num) * 14984549u ^ 11746499u);
}
ulong num5 = (ulong)num;
num5 <<= 32;
return num5 | (ulong)num2;
}