在 .NET 1.x 中,您可以在程序集上使用StrongNameIdentityPermissionAttribute,以确保只有您签名的代码才能访问您的程序集。根据 MSDN 文档,
在 .NET Framework 2.0 版及更高版本中,如果调用程序集具有完全信任,则对标识权限的要求无效。
这意味着任何完全信任的应用程序都可以绕过我的安全要求。
如何防止未经授权的代码访问我在 .NET 2.0 中的程序集?
在 .NET 1.x 中,您可以在程序集上使用StrongNameIdentityPermissionAttribute,以确保只有您签名的代码才能访问您的程序集。根据 MSDN 文档,
在 .NET Framework 2.0 版及更高版本中,如果调用程序集具有完全信任,则对标识权限的要求无效。
这意味着任何完全信任的应用程序都可以绕过我的安全要求。
如何防止未经授权的代码访问我在 .NET 2.0 中的程序集?
根据 Eric 的建议,我通过自己检查密钥来解决它。在我要保护的代码中,我添加了以下调用,
EnsureAssemblyIsSignedByMyCompany( Assembly.GetCallingAssembly() );
然后该方法的实现是
/// <summary>
/// Ensures that the given assembly is signed by My Company or Microsoft.
/// </summary>
/// <param name="assembly"></param>
private static void EnsureAssemblyIsSignedByMyCompany( Assembly assembly )
{
if ( assembly == null )
throw new ArgumentNullException( "assembly" );
byte[] pubkey = assembly.GetName().GetPublicKeyToken();
if ( pubkey.Length == 0 )
throw new ArgumentException( "No public key token in assembly." );
StringBuilder builder = new StringBuilder();
foreach ( byte b in pubkey )
{
builder.AppendFormat( "{0:x2}", b );
}
string pkString = builder.ToString();
if ( pkString != "b77a5c561934e089" /* Microsoft */ &&
pkString != "abababababababab" /* Ivara */ )
{
throw new ArgumentException( "Assembly is not signed by My Company or Microsoft. You do not have permission to call this code." );
}
}
** 更改名称和密钥以保护无辜者。任何与真实姓名或公司的相似之处都只是巧合。*
请参阅这篇文章:http:
//blogs.msdn.com/ericlippert/archive/2008/10/06/preventing-third-party-derivation-part-two.aspx
特别是这部分:
在最新版本的 .NET 中,“完全信任意味着完全信任”。也就是说,完全可信的代码满足所有需求,包括诸如“用这个密钥签名”之类的需求,无论它是否真的被签名。
这不是安全系统的致命缺陷吗?不,完全受信任的代码总是有能力做到这一点,因为完全受信任的代码有能力控制与给定程序集相关的证据。如果您可以控制证据,那么您可以伪造一个看起来像是来自微软的程序集,没问题。(如果您的进程中已经有恶意的完全信任代码,那么您已经失败了——它不需要模拟 Microsoft 签名的程序集;它已经有权执行用户可以执行的任何操作。)
显然,.Net 设计者认为这个属性对于 .Net 1.x 中的完全信任代码也不是很有效。
正如乔尔所指出的,您在 CAS 方面不走运。但是,您可以通过使用 Assembly.GetCallingAssembly() 以获取对包含调用代码的程序集的引用,然后手动检查该程序集上的强名称,以您需要保护的任何方法自己进行检查。