我在前一篇文章(Reflection带来的潜在威胁)中提到了通过Reflection访问private member所带来后果,这里接着这个话题来讨论应付这一问题的方法!
方法一:毫无疑问,那就是尽量不要把机密的代码发布出去。这也是最可靠的方法,然而很多情况下,我们做不到这一点,遇到这种情况我们也只好继续寻求其他解决方式……
方法二:通过制定StrongNameIdentityPermissionAttribute(感谢hBifTs提供的文章)来限制调用者的范围,如下所示:
方法三:在System.Diagnostics名字空间下有一个StackTrace的东东(我前不久刚用它写了一个写日志时详细记录Stack的辅助类,过两天我会把这个东东也Post上来 -- 哈哈,做了一次广告!),有了它,我们便可以得到调用者的信息,然后……好,废话少说,看看代码就知道了:
最后总结一下,方法一无疑是最可靠的,因此能遵循就尽量遵循。方法二无法起到保护作用,这里列出来只是表明方法三的思路来源于前者。方法三能基本达到我们的目的,但有许多局限性,如:别人依然可以通过Reflection看到我们的代码(用人说发布前使用混淆器,当然可以,不过保护代码不是本文关心的事情);或者运用各种手段跳过我们的检查……没有办法,既然你要在大街上走,就无法完全避免被人偷拍:)
下载该例子的完整代码:ReflectionTrap1.zip
方法一:毫无疑问,那就是尽量不要把机密的代码发布出去。这也是最可靠的方法,然而很多情况下,我们做不到这一点,遇到这种情况我们也只好继续寻求其他解决方式……
方法二:通过制定StrongNameIdentityPermissionAttribute(感谢hBifTs提供的文章)来限制调用者的范围,如下所示:
[StrongNameIdentityPermissionAttribute(SecurityAction.Demand, PublicKey="002400000...")]
private static string Decrypt(byte[] d)
{
}
SecurityManager.SecurityEnabled = false;
这样一来,我们的安全设置依然形同虚设。根据这种方法的原理--检查被调用者的身份,我想到了下面方法:方法三:在System.Diagnostics名字空间下有一个StackTrace的东东(我前不久刚用它写了一个写日志时详细记录Stack的辅助类,过两天我会把这个东东也Post上来 -- 哈哈,做了一次广告!),有了它,我们便可以得到调用者的信息,然后……好,废话少说,看看代码就知道了:
private static string Decrypt(byte[] d)
{
CheckCaller("SecLib, Version=1.0.1713.28332, Culture=neutral, PublicKeyToken=null");
...
}
private static void CheckCaller(string fullName)
{
StackTrace st = new StackTrace(2, false);
StackFrame sf = st.GetFrame(0);
MethodBase mb = sf.GetMethod();
if(mb.DeclaringType.Assembly.FullName != fullName)
throw new Exception("Invalid caller!");
}
最后总结一下,方法一无疑是最可靠的,因此能遵循就尽量遵循。方法二无法起到保护作用,这里列出来只是表明方法三的思路来源于前者。方法三能基本达到我们的目的,但有许多局限性,如:别人依然可以通过Reflection看到我们的代码(用人说发布前使用混淆器,当然可以,不过保护代码不是本文关心的事情);或者运用各种手段跳过我们的检查……没有办法,既然你要在大街上走,就无法完全避免被人偷拍:)
下载该例子的完整代码:ReflectionTrap1.zip