以编程方式检查 NuGet 包中经过身份验证的文件

Programmatically check authenticoded files in NuGet Package

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

场景:

我希望 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 规范 add.dll,nuget pack .\app.dll.nuspec)

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 服务器获取可用 NuGet 的列表(我使用的是 Nexus)
  2. 标记要安装的文件
  3. 软件包提供下载link:

    IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(<connectionString>);
    
    DataServicePackage package = (DataServicePackage) repo.FindPackage(packageId);
    String downloadUrl = package.DownloadUrl.AbsoluteUri;
    
  4. 下载安装包并存盘:

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. 使用文件存储的目录作为新存储库并从那里安装包
//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 包内的文件进行身份验证。

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

简单地检查包内的 dll 可能不是最安全的选择,因为可以将恶意文件添加到包中,从而危及您的 intent/machine。 NuGet 团队正在努力允许作者对包进行签名。在该过程中,您将拥有 NuGet.exe sign <package>NuGet.exe verify <package> 命令。您可以在 the blog post. The detailed specs are at - Sign Command and Verify Command.

阅读更多相关信息

更新- NuGet 团队已完成包签名和验证的实施。您现在可以按照 here and verify the integrity of a package (among other things) as described here.

中的说明签署包裹

您可以阅读技术规格 here