转载:.Net 程序集 签名工具sn.exe 密钥对SNK文件 最基本的用法
.Net 程序集 签名工具sn.exe 密钥对SNK文件 最基本的用法
阐述签名工具这个概念之前,我先说说它不是什么:
1.它不是用于给程序集加密的工具,它与阻止Reflector或ILSpy对程序集进行反编译一毛钱关系都没有。
2.它很讨厌人们把它和加密联系在一起。
我再说说它是什么:
1.起个大名字
sn是strong name的缩写,正如其名,sn.exe的目的是给程序集起一个唯一的名字(Hash+name+version+culture),即签名,保证不会让两个不同的DLL重名(就跟身份证不能重一样)
2.让调用者识别被调用的DLL是否被篡改
这一点是我重点要说的,我们先假设一个场景。一个黑客正在用一个银行客户端程序给一个账户转账,通过反编译发现,前端主程序Bank.exe调用Transfer.dll的TransferMoney方法来进行转账操作。他自然地想到,如果我修改了TransferMoney方法,将金额参数乘以10,然后重新编译成Transfer.dll再覆盖原来的Transfer.dll,他就能成为宇宙首富!
由这个例子得知,我们亟待解决的安全问题是,让Bank.exe有能力得知其调用的Transfer.dll是不是被别人篡改过的。那么我们很自然地会想到,用信息摘要算法呗~(废话一下,不同内容摘要出来的128位字符串是绝对不一样的)
是的!sn起的这个大名字就是这个摘要信息,我们可以在Bank.exe的引用信息里存好了我应该调用Transfer.dll的摘要值OriHash,这样我们就可以在调用时先摘要一下当前的Transfer.dll得出CurHash,然后比对一下OriHash和CurHash即可!过程如下图:
2.让调用者识别被调用的DLL是否被篡改
这一点是我重点要说的,我们先假设一个场景。一个黑客正在用一个银行客户端程序给一个账户转账,通过反编译发现,前端主程序Bank.exe调用Transfer.dll的TransferMoney方法来进行转账操作。他自然地想到,如果我修改了TransferMoney方法,将金额参数乘以10,然后重新编译成Transfer.dll再覆盖原来的Transfer.dll,他就能成为宇宙首富!
由这个例子得知,我们亟待解决的安全问题是,让Bank.exe有能力得知其调用的Transfer.dll是不是被别人篡改过的。那么我们很自然地会想到,用信息摘要算法呗~(废话一下,不同内容摘要出来的128位字符串是绝对不一样的)
是的!sn起的这个大名字就是这个摘要信息,我们可以在Bank.exe的引用信息里存好了我应该调用Transfer.dll的摘要值OriHash,这样我们就可以在调用时先摘要一下当前的Transfer.dll得出CurHash,然后比对一下OriHash和CurHash即可!过程如下图:
这似乎就是正确答案了,可是...
这样做有一个问题,就是关于你预先存好的那个摘要值OriHash。有两个方面:
方面1.一旦我正常地更新了Transfer.dll, 那摘要也就变了,也就是说你要通知Bank.exe去更新OriHash。
方面2.由问题1引发的安全问题。
对于方面1,我觉得是最主要的原因,一旦Transfer.dll更新了,为了比对摘要,Bank.exe需要更新OriHash,更新100次Transfer.dll,你就要更新100次OriHash,这个做法太要命了,当然这还只是麻烦层面的问题,更严重的是,我们可以想象到由于频繁更新OriHash而引发的安全问题。
对于方面2,由于你总去更新OriHash,这个环节一旦被黑客截获,你的OriHash就不一定保证是真的了,当然我个人认为这个怀疑有点过头了,因为DLL引用信息一般都是工具自动添加的,除非你通过某种网络机制传输这个OriHash到Bank.exe所属的项目文件(如Bank.csPRoj),此时OriHash就有了更多的被黑风险,这是一个安全问题!
所以基于以上两点,.Net拿出了非对称加密算法这把利剑!(再废话一下,非对称加密即生成一对儿钥匙——私钥和公钥,明文被该私钥加密只能用该公钥解密,反之亦然,所以私钥自己要绝对保密,公钥可以给任何人)
将OriHash用私钥加密为CodedHash,并存储在Transfer.dll中。然后在Bank.exe里一次性存入这个为了调用Transfer.dll的公钥,但一定要意识到,Transfer.dll里面是绝对没有私钥的,私钥只包含在myPair.snk文件中,也只有你拿着,并配以荷枪实弹的保安们誓死保护不被别人拿走。
那么新的验证流程如下,请结合下图:
a.首先Bank.exe里含有公钥,Transfer.dll里含有CodedHash
b.Bank.exe用公钥解密CodedHash
c1.若解密成功,就证明这个CodedHash是用和我公钥配对的那个私钥加密的。
c11.对Transfer.dll进行摘要得到CurHash,将其和解密的Hash对比,如果一样则证明Transfer.dll是安全的,并且是完整的,加载即可。如果不同,则证明这个Transfer.dll是别人篡改过的,此时拒绝加载Transfer.dll
c2.若解密失败,则证明这个CodedHash是用别的私钥加密的,也就是黑客弄的,此时同样拒绝加载Transfer.dll
这样的流程解决了之前的两个问题,即当Transfer.dll正常更新时,不用再把新的Hash传给Bank.exe了,Bank.exe只需用公钥去解密CodedHash便可知晓这东西是谁发的,并通过解密了的Hash和实时计算的Transfer.dll的Hash进行对比。这里我们逻辑上有个假定,那就是Bank.exe里的那个为了调用Transfer.dll的那个公钥是真的。如果你说这个被黑了怎么办,那我只能说,他都能改你这个Bank.exe里的公钥信息了,他就想改什么改什么了,你就束手就缚吧。另外如果你说,我们既然之前说怕传给Bank.exe的OriHash有假,那你为什么不怕传给Bank.exe的公钥有假?我只能说,你的逻辑很清晰,的确,我们无法保证,但我要说的是毕竟公钥只传一次,而OriHash有可能需要多次传输,风险概率不一样,如果我们假定Transfer.dll永不改变,也就是说OriHash也只用传一次,那我可以说你用不用非对称加密算法都是一样的,因为保证第一次给的OriHash是真的和保证第一次给的公钥是真的,这俩的风险系数是一样的。不知道这么说,大家能不能明白我的意思,我也是绕了好久才捋顺的。
我们可以再假设一遍黑客可能进行的攻击方法:(注意前提是黑客不能动Bank.exe以及内部的PubKey1)
攻击1:改动并覆盖了我的Transfer.dll,但CodedHash是一模一样的
这种情况下,对Transfer.dll摘要的Hash和PubKey1对CodedHash解密的结果Hash是不一样的,成功破案!
攻击2:改动并覆盖了我的Transfer.dll,黑客自己生成了公钥私钥对,并对Transfer.dll的Hash用私钥加密成CodedHash.
这种情况下,当我们用PubKey1解密CodedHash时,由于公钥PubKey1和黑客的私钥不成对,解密时解不开的,成功破案!
攻击3:改动并覆盖了我的Transfer.dll,而Transfer.dll根本不是签名编译的。
这种情况下,结果和前面两个是一样的,成功破案!
攻击4:黑客兄由于拿不着你的私钥,表示没有其它攻击方案了,T_T。
至此,原理总算是说明白了。下面我就介绍如何利用sn.exe来办这些事儿了。
我很讨厌MS把这么多重要的任务都包装在了sn.exe里,首先我们有两个工程Bank.csproj和Transfer.csproj,我们要做的就是实现上图的流程。
1.用sn.exe生成公钥私钥对文件myPair.snk。如下图:(你要誓死保护好myPair.snk,因为里面有私钥,且这也是私钥唯一存在的地方)
2.在Transfer工程中,将myPair.snk的路径填到AssemblyInfo.cs文件中,如下图:
3.编译Transfer工程,生成Transfer.dll。此时,编译器瞬间完成了对Transfer.dll的Hash,并用myPair.snk中的私钥加密了Hash成CodedHash,并将CodedHash存入Transfer.dll中,同时公钥信息也存入了Transfer.dll中(注意绝对没有私钥)。
4.在Bank工程中,重新引用Transfer.dll文件,重新编译Bank.exe,编译时编译器将提取Transfer.dll中的公钥PubKey1,并将其写在引用Dll的描述中。当我们用反编译工具查看Bank.exe时,我们可以查看到如下信息:
// Transfer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3d5e0147c186af58
PublicKeyToken即是我们所说的公钥PubKey1。
5.此时大功告成,无论有人用自己的私钥编译篡改了的Transfer.dll或者根本就没有用私钥签名编译,运行Bank.exe时会抛出如下信息:
这便是最基本的应用了,我也是参考了不少文章,其中比较重要的是http://www.windowsdevcenter.com/pub/a/dotnet/2003/04/28/strongnaming.html,该文章还介绍了延迟签名等机制,有兴趣的朋友可以看看。
在这里再次说明,sn.exe并不能对程序集加密阻止反编译,只是让调用者知道调用对象是不是想要的,仅此而已。
另外,HTTPS也是用的类似的方案来判断对方是不是自己人的,只是多了一个用对称加密算法加密数据包这一步,其它和这个都是一样的。
祝大家在园子里一起进步!
转自:http://www.knowsky.com/604600.html
转载:.Net 程序集 签名工具sn.exe 密钥对SNK文件 最基本的用法的更多相关文章
- .Net 程序集 签名工具sn.exe 密钥对SNK文件 最基本的用法
阐述签名工具这个概念之前,我先说说它不是什么: 1.它不是用于给程序集加密的工具,它与阻止Reflector或ILSpy对程序集进行反编译一毛钱关系都没有. 2.它很讨厌人们把它和加密联系在一起. 我 ...
- 【转】.Net 程序集 签名工具sn.exe 密钥对SNK文件 最基本的用法
阐述签名工具这个概念之前,我先说说它不是什么: 1.它不是用于给程序集加密的工具,它与阻止Reflector或ILSpy对程序集进行反编译一毛钱关系都没有. 2.它很讨厌人们把它和加密联系在一起. 我 ...
- 使用sn.exe为程序集签名
前言 在写上一篇随笔时,为理解EF事务底层的原理,我去Github上把EF的源码下载放到自己项目调试,不过在编译时遇到了下面这个报错信息.经过一番查阅,了解到了程序集签名(也称强名称签名)的概念.报错 ...
- Sn.exe(强名称工具)
Sn.exe(强名称工具) .NET Framework 4.5 强名称工具 (Sn.exe) 有助于使用强名称对程序集进行签名. Sn.exe 提供了用于密钥管理.签名生成和签名验证的选项. 强 ...
- iOS包重签名工具,ipa文件重签名,快速签名,SignTool签名工具,好用的签名工具,App重签名
新工具 ProjectTool 已上线 这是一款快速写白包工具,秒级别写H5游戏壳包,可视化操作,极易使用,支持Swift.Objecive-C双语言 QQ交流群:811715780 进入 Proje ...
- 使用SN.exe对.Net生成的程序集进行签名
CLR用数字签名的方式防止程序集发布后被人篡改,也可以确定发布人,这个方法就是使用公/私钥对,然后对程序集所有模块取一个哈希生成一个数字签名放在程序集的元数据中. 1.创建公/私钥对 创建公/ ...
- SignTool.exe(签名工具)
水漂收集 -- SignTool.exe(签名工具) =============C#.Net 篇目录============== 签名工具是一个命令行工具,用于用证书对文件进行数字签名,验证文件和时间 ...
- [工具推荐]004.EXE签名工具SignTool使用教程
数字证书,真是个神奇的东西,可以保证软件不被修改,可以表明文件的发布日期,最重要的,可以很大程度的减少杀毒软件的误报,当然,这就要使用可信任的机构颁发的证书了. 现在要说的不是申请证书,而是如何制作自 ...
- Android中APK签名工具之jarsigner和apksigner详解
一.工具介绍 jarsigner是JDK提供的针对jar包签名的通用工具, 位于JDK/bin/jarsigner.exe apksigner是Google官方提供的针对Android apk签名及验 ...
随机推荐
- 关于mysql中的count()函数
1.count()函数是用来统计表中记录的一个函数,返回匹配条件的行数. 2.count()语法: (1)count(*)---包括所有列,返回表中的记录数,相当于统计表的行数,在统计结果的时候,不会 ...
- JAVA多线程-实现同步
一.什么是线程安全问题 当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题.但是做读操作是不会发生数据冲突问题. 二.如何解决线程安全问题 1)如何 ...
- nodejs开发辅助工具nodemon
前面的话 修改代码后,需要重新启动 Express 应用,所做的修改才能生效.若之后的每次代码修改都要重复这样的操作,势必会影响开发效率,本文将详细介绍Nodemon,它会监测项目中的所有文件,一旦发 ...
- Python 离线 安装requests第三方库
一.介绍 requests是Python的一个HTTP客户端库,跟urllib,urllib2类似,不过requests的优势在于使用简单,相同一个功能,用requests实现起来代码量要少很多.毕竟 ...
- 【LOJ2586】【APIO2018】选圆圈 CDQ分治 扫描线 平衡树
题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1,c_2,\ldots,c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径最大的圆,选择编号最小的.记为 \ ...
- Hdoj 1847.Good Luck in CET-4 Everybody! 题解
Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载 ...
- zabbix数据库分表的实现
前提条件是主从同步操作完成(主从同步的前提是两个数据库表结构必须一样) 先看一下mysql配置文件 vi /usr/local/mysql/my.cnf 配置内容:------------------ ...
- 第四十篇-private,public,protected的区别
1.public: public表明该数据成员.成员函数是对所有用户开放的,所有用户都可以直接进行调用 2.private: private表示私有,私有的意思就是除了class自己之外,任何人都不可 ...
- 打怪升级之路—Security+认证通关攻略(401还是501)
我花了一个月才把题目过完一遍的(这一个月都上班,下班抽空做几页),这里面走了很多弯路,我把备考过程整理出来希望对大家有帮助. 我是在2019年1月完成的Security+考试,离安全牛课堂直播培训结束 ...
- Vue(小案例_vue+axios仿手机app)_上拉加载
---恢复内容开始--- 一.前言 ...