简体   繁体   English

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

[英]Programmatically check authenticoded files in NuGet Package

Is there a way to check a dll file inside a NuGet package when installing it using NuGet API. 使用NuGet API安装时,有没有办法检查NuGet包中的dll文件。

Scenario: 场景:

I want ac#/.net application to be able to update itself at runtime using NuGet packages. 我希望ac#/。net应用程序能够在运行时使用NuGet软件包进行更新。 Since this is obviously pretty risky I would like to verify that the package comes from the source I expect it to come from. 由于这显然很冒险,因此我想验证该软件包是否来自我期望的来源。

Problem: 问题:

NuGet does not support package signing. NuGet不支持程序包签名。 There is a paper addressing the issue here: https://blog.nuget.org/20150203/package-signing.html 此处有一篇解决该问题的论文: https : //blog.nuget.org/20150203/package-signing.html

What I have done so far: 到目前为止,我所做的是:

  1. Build an empty project 建立一个空项目
  2. Sign the dll file (signtool sign /t http://timestamp.digicert.com /a ".\\app.dll") 对dll文件进行签名(signtool登录/ t http://timestamp.digicert.com / a“。\\ app.dll”)
  3. Create a NuGet package from it (nuget spec add.dll, nuget pack .\\app.dll.nuspec) 从中创建一个NuGet包(nuget spec add.dll,nuget pack。\\ app.dll.nuspec)

The dll file inside the NuGet package is now signed and I can upload it to a NuGet repo. NuGet软件包中的dll文件现在已签名,我可以将其上传到NuGet存储库。

This is my application code: 这是我的应用程序代码:

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);
    }

The example is taken from here: 该示例从此处获取:

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

The only possible solution I can imagine at the moment would be to use a download package function from the NuGet API, unpack the downloaded package, do the check and install afterwards. 我目前能想到的唯一可能的解决方案是使用NuGet API的下载软件包功能,解压缩下载的软件包,然后进行检查并安装。 Sadly I can not find any hint in the API that the install process could be done in those two steps. 可悲的是,我在API中找不到任何提示可以在这两个步骤中完成安装过程。

Alternatively, I could use PGP to create a detached signature, sign the NuGet package itself and do a check on the NuGet package with the detached signature. 或者,我可以使用PGP创建分离的签名,对NuGet包本身进行签名,并使用分离的签名对NuGet包进行检查。 However, that leads to the same problem of first being able to download the package. 但是,这会导致同样的问题,首先需要下载该软件包。

I would be grateful for any hint! 我将不胜感激! Thank you. 谢谢。

--- Update --- -更新-

I think I have found a way to use NuGet and PGP signing for package verification. 我想我已经找到一种使用NuGet和PGP签名进行软件包验证的方法。 I am doing the following: 我正在执行以下操作:

  1. Get list of available NuGets from NuGet Server (I am using Nexus) 从NuGet服务器获取可用的NuGet列表(我正在使用Nexus)
  2. Mark a file for installation 将文件标记为要安装
  3. The Package provides a download link: 该软件包提供了一个下载链接:

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

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. Download the detached signature from a different server 从其他服务器下载分离的签名
  2. Verify the detached signature and the downloaded nupkg (I used BouncyCastle) 验证分离的签名和下载的nupkg(我使用BouncyCastle)
  3. If verification succeeds: 如果验证成功:
  4. Use the directory the file is stored as new repository and install the package from there 使用文件存储为新存储库的目录并从那里安装软件包
//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>);

Using this approach still leaves you with the possibility to authenticode the files inside the NuGet package. 使用这种方法仍然使您可以对NuGet包中的文件进行身份验证。

Happy to hear what you guys think about this solution. 很高兴听到你们对这个解决方案的看法。 Thanks! 谢谢!

Simply checking the dlls inside a package may not be the safest option as a malicious file can be added the package which can compromise your intent/machine. 仅检查软件包中的dll可能不是最安全的选择,因为可以在软件包中添加恶意文件,这可能会损害您的意图/机器。 The NuGet team is working on allowing author signing for packages. NuGet团队正在努力允许作者签署软件包。 In that process you will have NuGet.exe sign <package> and NuGet.exe verify <package> commands. 在此过程中,您将使用NuGet.exe sign <package>NuGet.exe verify <package>命令。 You can read more about it the the blog post . 您可以在博客文章中了解更多信息 The detailed specs are at - Sign Command and Verify Command . 详细的规范是at- Sign命令Verify Command


Update - NuGet team has finished implementing package signing and verification. 更新-NuGet团队已完成实现包签名和验证。 You can now sign a package, as described here and verify the integrity of a package (among other things) as described here . 现在您可以注册一个包,描述在这里和验证包的完整性(除其他事项外)所描述的在这里

You can read about the technical specifications here . 您可以在此处阅读有关技术规格的信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM