单声道强名称验证失败



我在Ubuntu上使用Mono。

在过去的某个时候(当我使用库存时,来自 Ubuntu 存储库的古老 monodevelop)以下方法有效:

  1. sn -k mykey.snk
  2. 在 .csproj 中,将<AssemblyOriginatorKeyFile>设置为上述 .snk
  3. 在同一 .csproj 中,将<SignAssembly>设置为true
  4. 在运行时,通过使用以下源模拟 Mono sn 工具来自我验证.exe:
private static bool IsStrongNameSigned(string fileName)
{
// For details see
// https://github.com/mono/mono/blob/master/mcs/tools/security/sn.cs
const int keySize = 12, blobSize = 148;
var an = AssemblyName.GetAssemblyName(fileName);
byte[] publicKey = an.GetPublicKey();
if (publicKey == null ||
publicKey.Length < keySize + blobSize)
return false;
using (RSA rsa = CryptoConvert.FromCapiPublicKeyBlob(
blob: publicKey, offset: keySize))
{
var sn = new StrongName(rsa);
return sn.Verify(fileName);
}
}

现在,如果我尝试上述操作,sn。Verify() 返回 false,即使项目已被明确告知在构建时签名。

失败的代码在 Mono.Security 中:

$ dpkg -S /usr/lib/mono/4.5-api/Mono.Security.dll
mono-devel: /usr/lib/mono/4.5-api/Mono.Security.dll
$ apt-cache show mono-devel
Package: mono-devel
Source: mono
Version: 5.0.1.1-0xamarin5+debian7b1
Architecture: all
Maintainer: Debian Mono Group <pkg-mono-group@lists.alioth.debian.org>
Installed-Size: 75560
...

调试后,似乎具体的故障点在强哈希中。签名确实被读取,但它由一个 128 字节的全零数组组成。

我可以确认 MonoDevelop 7.1 IDE 告诉 csc 使用密钥;请注意/publicsign+/keyfile的存在:

/usr/lib/mono/4.5/csc.exe /noconfig /nowarn:1701,1702,2008 
/nostdlib+ /platform:anycpu32bitpreferred
/errorreport:prompt /warn:4 /define:DEBUG /errorendlocation
/preferreduilang:en-CA /highentropyva+ /reference:...
/debug+ /debug:portable
/keyfile:/home/....snk /optimize- /out:....exe
/subsystemversion:6.00 /resource:gtk-gui/gui.stetic,gui.stetic
/target:exe /utf8output /publicsign+ ....cs 

我的问题是:

  • Mono 中发生了哪些变化,现在阻止了这种方法的工作?
  • 是否有更好的方法来验证程序集?
  • 是生成无法对程序集进行签名,还是验证码找不到签名?是否有一些单独的工具可以确认哪种情况?

我认为公共签名(/publicsign+)是罪魁祸首。与延迟签名类似,它不会使用私钥生成签名,因此对于 .NET Framework 项目,运行时强名称验证将失败。

根据您的观察,Mono 项目的验证也会失败,我认为这是设计使然。您不应使用公共签名,然后它可能会开始工作。

最新更新