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

标签 c# .net nuget signing authenticode

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

场景:

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

问题:

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)

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. 该软件包提供下载链接:

    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 可能不是最安全的选择,因为可以将恶意文件添加到包中,从而危及您的意图/机器。 NuGet 团队正在努力允许作者对包进行签名。在那个过程中你会得到 NuGet.exe sign <package>NuGet.exe verify <package>命令。您可以阅读更多相关信息 the blog post .详细规范位于 - Sign CommandVerify Command .


更新 - NuGet 团队已完成包签名和验证的实现。您现在可以按照描述签署包裹 here并按照 here 所述验证包的完整性(除其他外) .

您可以阅读技术规范 here .

关于c# - 以编程方式检查 NuGet 包中经过身份验证的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46792863/

相关文章:

c# - .NET服务失败时,系统是否会记录异常?

c# - 如何使用 NuGet 打包命令行工具?

visual-studio - 术语 'nuget' 无法识别

c# - C# 中集合的 XML 序列化

c# - 在 WCF REST 服务中禁用 XML 示例?

c# - 在 .NET 中将属性公开为变体以进行互操作

c# - 有效去除具有相同斜率的点

c# - 项目引用不会编译 'should be reference'

c# - 鼠标悬停在网格中具有路径的事件上无法按预期工作,wpf

c# - 安装 Json.Net 并在项目中引用它后出错。 window 电话 8