C# 计算VS_密钥容器名称

C# 计算VS_密钥容器名称,c#,visual-studio-2010,msbuild,private-key,C#,Visual Studio 2010,Msbuild,Private Key,如何计算VS_密钥容器名称?它们通常是这样的:VS_key71E582524;B54D29 我假设它是基于计算机名的,但是如果我们有一个云服务在运行,每次实例重新启动时都随机更改计算机名呢 当实例启动时,我们需要有容器名称,这样我们就知道将私钥存储到哪个容器中,以便构建工具和所有工具正常工作。我们需要自动设置容器名称 因此,基本上,我们需要找到一种方法,在每次计算机重新启动时生成正确的容器名称。有什么提示或帮助吗?我们在尝试在集成服务器上自动注册密钥时遇到了这个问题。必须运行Visual Stu

如何计算VS_密钥容器名称?它们通常是这样的:VS_key71E582524;B54D29

我假设它是基于计算机名的,但是如果我们有一个云服务在运行,每次实例重新启动时都随机更改计算机名呢

当实例启动时,我们需要有容器名称,这样我们就知道将私钥存储到哪个容器中,以便构建工具和所有工具正常工作。我们需要自动设置容器名称


因此,基本上,我们需要找到一种方法,在每次计算机重新启动时生成正确的容器名称。有什么提示或帮助吗?

我们在尝试在集成服务器上自动注册密钥时遇到了这个问题。必须运行Visual Studio或MSBuild来提取VS_密钥是不可接受的。然后,通过最详细地研究MSBuild的日志,我发现了以下几点

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

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

第一个解决方案:创建ResolveKeySource实例并调用适当的方法。由于您不提供密码和其他信息,它将引发一个异常,其消息包含强大的VS_密钥

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;
    }
public静态字符串GetLocalUserKeyContainerByGeneration(字符串键文件){
字符串localName=Environment.UserDomainName+“\\”+Environment.UserName;
FileStream keyFileStream=null;
试一试{
keyFileStream=File.OpenRead(keyFile);
int num=(int)keyFileStream.Length;
字节[]数组=新字节[num];
读取(数组,0,num);
ulong hash1=HashFromBlob(数组);
byte[]bytes=Encoding.Unicode.GetBytes(localName.ToLower(CultureInfo.InvariantCulture));
返回“VS_KEY”+(hash1^HashFromBlob(bytes)).ToString(“X016”,CultureInfo.InvariantCulture);
}
最后{
if(keyFileStream!=null){
keyFileStream.Close();
}
}
}
私有静态ulong HashFromBlob(字节[]数据){
uint num=17339221u;
uint num2=19619429u;
uint num3=10803503u;
for(int i=0;inum5这个答案与@kdrapel的答案一致,但我无法将它放在评论中。我不得不对它进行一些修改,以找出如何在内联任务中实际使用它,所以我想我会与大家分享

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Test" ToolsVersion="4.0" >

  <Target Name="Test">
    <CalcKey InputKey="c:\path\to\your\key.pfx">
      <Output PropertyName="VSKEY" TaskParameter="VSKEY"/>
    </CalcKey>
    <Message Text="VSKey = $(VSKEY)"/>
  </Target>

  <UsingTask
      TaskName="CalcKey"
      TaskFactory="CodeTaskFactory"
      AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
    <ParameterGroup>
      <InputKey ParameterType="System.String" Required="true"/>
      <VSKEY ParameterType="System.String" Output="true"/>
    </ParameterGroup>
    <Task>
      <Reference Include="$(MSBuildBinPath)\Microsoft.Build.Framework.dll"/>
      <Reference Include="$(MSBuildBinPath)\Microsoft.Build.Utilities.v12.0.dll"/>
      <Reference Include="$(MSBuildBinPath)\Microsoft.Build.Tasks.v12.0.dll"/>
      <Using Namespace="System.Text.RegularExpressions"/>
      <Using Namespace="Microsoft.Build.Tasks"/>
      <Code Type="Fragment" Language="cs">
        <![CDATA[
            var key = new ResolveKeySource();
            key.KeyFile = InputKey;
            try
            {
                key.Execute();
            }
            catch (Exception e)
            {
                var match = Regex.Match(e.Message, "VS_KEY_[A-F0-9]+");
                if (match.Success)
                {
                    this.VSKEY = match.Value;
                }
            }
]]>
      </Code>
    </Task>
  </UsingTask>

</Project>




添加答案作为评论是有限的