以编程方式检查NuGet包中的已验证文件

时间:2017-10-17 14:42:04

标签: c# .net nuget signing authenticode

使用NuGet API安装时,有没有办法检查NuGet包中的dll文件。

情景:

我希望c#/ .net应用程序能够在运行时使用NuGet包更新自身。由于这显然是非常危险的,我想验证包是否来自我希望它来自的来源。

问题:

NuGet不支持包签名。这里有一篇论文解决了这个问题:https://blog.nuget.org/20150203/package-signing.html

到目前为止我做了什么:

  1. 构建一个空项目
  2. 签署dll文件(signtool sign / t http://timestamp.digicert.com / a“。\ app.dll”)
  3. 从中创建一个NuGet包(nuget spec add.dll,nuget pack。\ app.dll.nuspec)
  4. NuGet包中的dll文件现已签名,我可以将其上传到NuGet仓库。

    这是我的应用程序代码:

    public static void installPackage(string packageId, string connectionString, string path){
            IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(connectionString);
    
            PackageManager packageManager = new PackageManager(repo, path);
    
            packageManager.InstallPackage(packageId);
        }
    

    这个例子来自这里:

    https://blog.nuget.org/20130520/Play-with-packages.html

    目前唯一可以想象的解决方案是使用NuGet API的下载包功能,解压缩下载的包,然后进行检查和安装。遗憾的是,我在API中找不到任何提示可以在这两个步骤中完成安装过程。

    或者,我可以使用PGP创建一个分离的签名,签署NuGet包本身并使用分离的签名检查NuGet包。但是,这导致了首先能够下载软件包的相同问题。

    我会感激任何暗示!谢谢。

    ---更新---

    我想我找到了一种使用NuGet和PGP签名进行包验证的方法。我正在做以下事情:

    1. 从NuGet Server获取可用的NuGets列表(我正在使用Nexus)
    2. 标记要安装的文件
    3. 该软件包提供下载链接:

      IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(<connectionString>);
      
      DataServicePackage package = (DataServicePackage) repo.FindPackage(packageId);
      String downloadUrl = package.DownloadUrl.AbsoluteUri;
      
    4. 将软件包下载并存储在磁盘上:

    5. using (var client = new WebClient()){
          client.UseDefaultCredentials = true;
          client.Credentials = new NetworkCredential(<User>, <Pass>);
          var content = client.DownloadData(downloadUrl);
          using (MemoryStream memoryStream = new MemoryStream(content)){
              FileStream fs = new FileStream(<pathToLocalRepo>, FileMode.CreateNew);
              memoryStream.CopyTo(fs);
              fs.Close();
          }
      }
      
      1. 从其他服务器下载分离的签名
      2. 验证分离的签名和下载的nupkg(我使用的是BouncyCastle)
      3. 如果验证成功:
      4. 使用该文件存储的目录作为新存储库并从那里安装包
      5. //Initialize local repository
        string path = <pathToLocalRepo>;
        IPackageRepository localRepo = PackageRepositoryFactory.Default.CreateRepository(path);
        var packages = repo.GetPackages();
        //Initialize the package manager
        PackageManager packageManager = new PackageManager(localRepo, path);
        //Install
        packageManager.InstallPackage(<packageId>);
        

        使用这种方法仍然可以对NuGet包中的文件进行身份验证。

        很高兴听到你们对这个解决方案的看法。谢谢!

1 个答案:

答案 0 :(得分:0)

简单地检查包中的dll可能不是最安全的选项,因为恶意文件可以添加到可能危害您的意图/机器的包中。 NuGet团队正致力于允许作者签名包。在该过程中,您将拥有NuGet.exe sign <package>NuGet.exe verify <package>命令。您可以在the blog post了解更多相关信息。详细规格位于 - Sign CommandVerify Command

更新 - NuGet团队已完成包签名和验证。您现在可以按照here所述签署一个包,并按照here所述验证包的完整性(以及其他内容)。

您可以阅读有关技术规范here的信息。