计算VS_KEY容器名称

Mik*_*ike 2 c# msbuild visual-studio-2010 private-key

如何计算VS_KEY容器名称?它们通常是这样的:VS_KEY_71E582524B5DDE29.

我假设它基于计算机名称,但如果我们运行的云服务每次实例重新启动时随机更改计算机名称会怎么样?

我们需要在实例启动时拥有容器名称,以便我们知道将私钥存储到哪个容器中,因此构建工具和所有工作都应该如此.我们需要自动设置容器名称.

所以基本上我们需要找到一种方法来在每次计算机重新启动时生成正确的容器名称.任何提示或帮助?

小智 7

我们在尝试在集成服务器上自动注册密钥时尝试了这个问题.必须运行Visual Studio或MSBuild来提取VS_KEY是不可接受的.然后通过调查具有最大冗长度的MSBuild的日志,我发现了以下内容.

此密钥是通过Microsoft.Build.Tasks.v4.0.dll(存在于GAC中)生成的.这个DLL中有一个名为"ResolveKeySource"的类.通过使用ILSpy或Reflector查看代码,您将看到一个调用ResolveAssemblyKey的Execute方法.这种方法是VS_KEY_xxxxxx之谜的核心.

通过使用Environment.UserDomainName和Environment.UserName散列密钥的内容来生成VS_KEY_xxxxx值.

第一个解决方案:您创建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;
   }
}
Run Code Online (Sandbox Code Playgroud)

第二种解决方案:获取生成此哈希码的代码,并使用它直接获取值而不会出现异常.这或多或少是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;
    }
Run Code Online (Sandbox Code Playgroud)