以编程方式检查 NuGet 包中经过身份验证的文件
Programmatically check authenticoded files in NuGet Package
有没有办法在使用 NuGet 安装时检查 NuGet 包中的 dll 文件 API。
场景:
我希望 c#/.net 应用程序能够在运行时使用 NuGet 包更新自身。因为这显然是相当冒险的,所以我想验证这个包是否来自我期望的来源。
问题:
NuGet 不支持包签名。这里有一篇论文解决了这个问题:https://blog.nuget.org/20150203/package-signing.html
到目前为止我做了什么:
- 构建一个空项目
- 对dll文件进行签名(signtool sign /t http://timestamp.digicert.com /a ".\app.dll")
- 从中创建一个 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 签名进行包验证的方法。我正在执行以下操作:
- 从 NuGet 服务器获取可用 NuGet 的列表(我使用的是 Nexus)
- 标记要安装的文件
软件包提供下载link:
IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(<connectionString>);
DataServicePackage package = (DataServicePackage) repo.FindPackage(packageId);
String downloadUrl = package.DownloadUrl.AbsoluteUri;
下载安装包并存盘:
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();
}
}
- 从不同的服务器下载分离的签名
- 验证分离签名和下载的nupkg(我用的是BouncyCastle)
- 如果验证成功:
- 使用文件存储的目录作为新存储库并从那里安装包
//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。
有没有办法在使用 NuGet 安装时检查 NuGet 包中的 dll 文件 API。
场景:
我希望 c#/.net 应用程序能够在运行时使用 NuGet 包更新自身。因为这显然是相当冒险的,所以我想验证这个包是否来自我期望的来源。
问题:
NuGet 不支持包签名。这里有一篇论文解决了这个问题:https://blog.nuget.org/20150203/package-signing.html
到目前为止我做了什么:
- 构建一个空项目
- 对dll文件进行签名(signtool sign /t http://timestamp.digicert.com /a ".\app.dll")
- 从中创建一个 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 签名进行包验证的方法。我正在执行以下操作:
- 从 NuGet 服务器获取可用 NuGet 的列表(我使用的是 Nexus)
- 标记要安装的文件
软件包提供下载link:
IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(<connectionString>); DataServicePackage package = (DataServicePackage) repo.FindPackage(packageId); String downloadUrl = package.DownloadUrl.AbsoluteUri;
下载安装包并存盘:
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();
}
}
- 从不同的服务器下载分离的签名
- 验证分离签名和下载的nupkg(我用的是BouncyCastle)
- 如果验证成功:
- 使用文件存储的目录作为新存储库并从那里安装包
//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。