<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Overskill...</title>
	<atom:link href="http://liar.pangwa.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://liar.pangwa.com</link>
	<description>每天灌水一点点</description>
	<lastBuildDate>Thu, 01 Sep 2011 14:33:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>安全，安全&#8230;2&#8230;强命名程序集</title>
		<link>http://liar.pangwa.com/2011/08/29/%e5%ae%89%e5%85%a8%ef%bc%8c%e5%ae%89%e5%85%a82%e5%bc%ba%e5%91%bd%e5%90%8d%e7%a8%8b%e5%ba%8f%e9%9b%86/</link>
		<comments>http://liar.pangwa.com/2011/08/29/%e5%ae%89%e5%85%a8%ef%bc%8c%e5%ae%89%e5%85%a82%e5%bc%ba%e5%91%bd%e5%90%8d%e7%a8%8b%e5%ba%8f%e9%9b%86/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 09:34:51 +0000</pubDate>
		<dc:creator>lie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[安全]]></category>
		<category><![CDATA[技术]]></category>

		<guid isPermaLink="false">http://liar.pangwa.com/2011/08/29/%e5%ae%89%e5%85%a8%ef%bc%8c%e5%ae%89%e5%85%a82%e5%bc%ba%e5%91%bd%e5%90%8d%e7%a8%8b%e5%ba%8f%e9%9b%86/</guid>
		<description><![CDATA[书接上回，说说.NET强命名（StrongName）。首先，强命名是什么？有什么用？简单地说，强命名是一种数字签名，目的是是为了防止程序集被篡改（好吧，还有很多其他作用，比如版本控制，唯一标识，等等。不过本篇blog主要目的是从安全角度来讲强命名）。 先回头怎么利用数字签名防止消息被篡改？参考前一篇blog关于使用消息签名防篡改的部分：“消息发布者使用不可逆算法（如SHA）计算出消息摘要，再用私钥加密消息摘要生成出数字签名，然后将消息与数字签名一起发布；消息接收者使用同样算法根据消息生成出消息摘要，再用消息发布者的公钥解密数字签名并将结果与消息摘要比较，以此验证消息是否被篡改过”。 怎么利用数字签名防止程序集被篡改？程序集本身，也可以看作一种包括了各种元数据，IL等等的消息。所以类似的，要防止程序集被篡改，程序集发布者需要一个公私钥对，并且需要一个生成程序集摘要的不可逆算法（.NET在此使用SHA-1算法）。 有了这些东西，我们先按自己的理解来设计.NET程序集的防篡改机制。假设我们需要发布一个程序集TestLib。首先，我们根据程序集内容生成程序集摘要，然后再用私钥加密摘要生成签名。可以将签名写到程序集文件里面去，这样我们只需要发布一个程序集文件，就能包括程序集内容本身和防篡改的签名。好了，我们可以把包含签名的程序集文件TestLib.dll发布出去了。 用户得到这个程序集，然后在自己的程序里引用这个程序集，为了简化问题，我们先只考虑用户不用程序集全名引用的情况。也就是说，在用户的project文件中（比如TestProject.csproj）中有类似这样的语句：&#60;Reference Include=&#34;TestLib&#34;/&#62;。用户编译运行自己的程序，当TestLib被用到的时候，CLR会尝试去加载TestLib并作防篡改验证。首先，CLR根据TestLib的内容生成程序集摘要；然后，CLR用我们的公钥解密TestLib中的签名部分，与生成的程序集摘要做比较…？！等等，CLR怎么得到我们的（TestLib发行者）的公钥呢？ 最直观地，当我们发布程序集的时候，类似签名，可以把公钥也写到程序集文件里面。这样，当CLR加载TestLib程序集的时候，就可以从程序集文件里读出公钥和签名，然后用公钥解密签名，再用得到的摘要与生成出来的摘要对比，以验证程序集是否被篡改过。 总结一下，为了防篡改，按照我们的想法，程序集里面除了有本身的的内容（IL，元数据等等），还需要有签名和公钥。翻翻MSDN关于强命名的部分，和我们想象的一样。程序集发布者首先需要（比如用sn.exe）生成自己的公私钥对，然后在build的时候，签名会被生成出来写到程序集中，相应的公钥也会被写到程序集中。这样的一个程序集就是一个强命名的程序集。 …这种做法，漏洞很大。在上一篇blog中提到过，利用消息签名防篡改有个重要的前提：“消息接收者都能拿到消息发送者真正的公钥，设想假如某些消息接收者拿到了假的公钥…那么拥有对应假私钥的篡改者就能任意篡改数据了”。.NET的做法，将公钥与需要防篡改的程序集一起发布，那么假如篡改者拿到这个程序集，改掉部分代码，然后用自己的私钥生成签名，和自己的公钥一起替换掉原来程序集文件里的签名和公钥部分。那么CLR是检测不出来的。更简单一点，篡改者改掉代码，然后直接抹去原来程序集文件里的签名和公钥即可。 有这么大的漏洞为什么.NET还要用这种将公钥写进程序集文件然后一起发布的做法？这是因为一般情况下，用户引用强命名程序集，会用全名，类似“TestLib, Version=1.2, PublicKeyToken=&#34;acc2372848326618&#34;”这样。这里解释一下，PublicKeyToken是根据公钥（PublicKey）用某种哈希算法算出来的，目的是引用程序集的时候不用完整写出很长的公钥字段，当然，用户也可以选择不用PublicKeyToken，而直接写PublicKey=”XXXXXX”这样。好，回到正题。那么当CLR加载TestLib的时候，从程序集里读出的公钥（PublicKey）如果与用户指定的公钥不符合，那么加载失败，CLR认为用户想要的程序集要么不存在，要么被篡改过。 基于这种用户指定全名的做法，假设用户在一开始就得到了真正的程序集，里面有真正的公钥（通过某种不存在的100%安全的方式…你懂得- -），那么篡改者就很难篡改了。 再总结一下，没有100%的安全，就算是用户指定全名的做法，也有需要用户在一开始就得到真正的程序集（包括真正的公钥）的假设。这个世界上毕竟没有完美的系统…正如前一篇blog提到的，一个安全系统的建立，还是要在某个安全假设成立的前提下…]]></description>
			<content:encoded><![CDATA[<p>书接上回，说说.NET强命名（StrongName）。首先，强命名是什么？有什么用？简单地说，强命名是一种数字签名，目的是是为了防止程序集被篡改（好吧，还有很多其他作用，比如版本控制，唯一标识，等等。不过本篇blog主要目的是从安全角度来讲强命名）。</p>
<p>先回头怎么利用数字签名防止消息被篡改？参考前一篇blog关于使用消息签名防篡改的部分：“消息发布者使用不可逆算法（如SHA）计算出消息摘要，再用私钥加密消息摘要生成出数字签名，然后将消息与数字签名一起发布；消息接收者使用同样算法根据消息生成出消息摘要，再用消息发布者的公钥解密数字签名并将结果与消息摘要比较，以此验证消息是否被篡改过”。</p>
<p>怎么利用数字签名防止程序集被篡改？程序集本身，也可以看作一种包括了各种元数据，IL等等的消息。所以类似的，要防止程序集被篡改，程序集发布者需要一个<strong>公私钥对</strong>，并且需要一个<strong>生成程序集摘要的不可逆算法</strong>（.NET在此使用SHA-1算法）。</p>
<p>有了这些东西，我们先按自己的理解来设计.NET程序集的防篡改机制。假设我们需要发布一个程序集TestLib。首先，我们根据程序集内容生成程序集摘要，然后再用私钥加密摘要生成签名。可以将签名写到程序集文件里面去，这样我们只需要发布一个程序集文件，就能包括程序集内容本身和防篡改的签名。好了，我们可以把包含签名的程序集文件TestLib.dll发布出去了。</p>
<p>用户得到这个程序集，然后在自己的程序里引用这个程序集，为了简化问题，我们先只考虑用户不用程序集全名引用的情况。也就是说，在用户的project文件中（比如TestProject.csproj）中有类似这样的语句：&lt;Reference Include=&quot;TestLib&quot;/&gt;。用户编译运行自己的程序，当TestLib被用到的时候，CLR会尝试去加载TestLib并作防篡改验证。首先，CLR根据TestLib的内容生成程序集摘要；然后，CLR用我们的公钥解密TestLib中的签名部分，与生成的程序集摘要做比较…？！等等，CLR怎么得到我们的（TestLib发行者）的公钥呢？</p>
<p>最直观地，当我们发布程序集的时候，类似签名，可以把公钥也写到程序集文件里面。这样，当CLR加载TestLib程序集的时候，就可以从程序集文件里读出公钥和签名，然后用公钥解密签名，再用得到的摘要与生成出来的摘要对比，以验证程序集是否被篡改过。</p>
<p>总结一下，为了防篡改，按照我们的想法，程序集里面除了有<strong>本身的的内容</strong>（IL，元数据等等），还需要有<strong>签名和公钥</strong>。翻翻MSDN关于强命名的部分，和我们想象的一样。程序集发布者首先需要（比如用sn.exe）生成自己的公私钥对，然后在build的时候，签名会被生成出来写到程序集中，相应的公钥也会被写到程序集中。这样的一个程序集就是一个强命名的程序集。</p>
<p>…这种做法，漏洞很大。在上一篇blog中提到过，利用消息签名防篡改有个重要的前提：“消息接收者都能拿到消息发送者真正的公钥，设想假如某些消息接收者拿到了假的公钥…那么拥有对应假私钥的篡改者就能任意篡改数据了”。.NET的做法，将公钥与需要防篡改的程序集一起发布，那么假如篡改者拿到这个程序集，改掉部分代码，然后用自己的私钥生成签名，和自己的公钥一起替换掉原来程序集文件里的签名和公钥部分。那么CLR是检测不出来的。更简单一点，篡改者改掉代码，然后直接抹去原来程序集文件里的签名和公钥即可。</p>
<p>有这么大的漏洞为什么.NET还要用这种将公钥写进程序集文件然后一起发布的做法？这是因为一般情况下，用户引用强命名程序集，会用全名，类似“TestLib, Version=1.2, PublicKeyToken=&quot;acc2372848326618&quot;”这样。这里解释一下，PublicKeyToken是根据公钥（PublicKey）用某种哈希算法算出来的，目的是引用程序集的时候不用完整写出很长的公钥字段，当然，用户也可以选择不用PublicKeyToken，而直接写PublicKey=”XXXXXX”这样。好，回到正题。那么当CLR加载TestLib的时候，从程序集里读出的公钥（PublicKey）如果与用户指定的公钥不符合，那么加载失败，CLR认为用户想要的程序集要么不存在，要么被篡改过。</p>
<p>基于这种用户指定全名的做法，假设用户在一开始就得到了真正的程序集，里面有真正的公钥（通过某种不存在的100%安全的方式…你懂得- -），那么篡改者就很难篡改了。</p>
<p>再总结一下，没有100%的安全，就算是用户指定全名的做法，也有需要用户在一开始就得到真正的程序集（包括真正的公钥）的假设。这个世界上毕竟没有完美的系统…正如前一篇blog提到的，一个安全系统的建立，还是要在某个安全假设成立的前提下…</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.pangwa.com/2011/08/29/%e5%ae%89%e5%85%a8%ef%bc%8c%e5%ae%89%e5%85%a82%e5%bc%ba%e5%91%bd%e5%90%8d%e7%a8%8b%e5%ba%8f%e9%9b%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>安全，安全&#8230;1&#8230;公钥私钥</title>
		<link>http://liar.pangwa.com/2011/08/26/%e5%ae%89%e5%85%a8%ef%bc%8c%e5%ae%89%e5%85%a81/</link>
		<comments>http://liar.pangwa.com/2011/08/26/%e5%ae%89%e5%85%a8%ef%bc%8c%e5%ae%89%e5%85%a81/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 06:12:58 +0000</pubDate>
		<dc:creator>lie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[安全]]></category>
		<category><![CDATA[技术]]></category>

		<guid isPermaLink="false">http://liar.pangwa.com/2011/08/26/%e5%ae%89%e5%85%a8%ef%bc%8c%e5%ae%89%e5%85%a81/</guid>
		<description><![CDATA[前一段做了很多安全相关的东西，简单总结一下。 Public Key Cryptography 首先，最基础的，也是目前应用广泛的公私钥加解密理论（公开密钥加密 public key cryptography，又称非对称加密），简单地说指的是公钥和私钥成对被创建，一段信息被公钥加密后只能用对应私钥解密，类似的，一段信息被私钥加密后只能用对应公钥解密。 为什么把这对密钥叫做公钥和私钥呢？假设某人A生成了一对公私钥，公钥是公共的可以告诉其他人的密钥，而私钥是私有的需要保密的的密钥。 这个理论有什么用呢？典型的两个用途，一是消息加密（防截获破解），二是消息签名（防篡改）。 消息加密 先说消息加密。假设A需要发送消息给B。那么A可以用B的公钥加密消息，然后将加密后的消息发送给B。B得到加密后的消息，用自己的私钥解密，就能获得这条消息。假设因为传输不安全，加密后的消息被C截获，因为C并没有B的私钥。也就不能解密这条消息。但是这样做并不能防篡改，假设B获得一条声称是发给自己的消息，B并没有办法验证这条消息有没有被篡改。防篡改的内容在下一节讲到。 先暂时跳出公私钥加解密理论的框架。说下对称加密。对称加密很好理解，一段消息用一个密钥加密过后，也要用同样的密钥解密。回过头看上面的例子，假如A要安全地发送消息给B，或者发给很多人，那假如大家都知道密钥的情况下。A只需要用这个密钥加密消息，然后发送给大家，接收者各自用这个密钥解密。这样在大家都安全地拥有这个密钥的情况下自然不会有问题。不过问题又来了，在密钥被生成出来的时候，如何安全地把这个密钥传送给A以及其他接收者呢？鸡生蛋，蛋生鸡…当然，可以跳出这个系统，怎样安全地把这个密钥传送给A以及其他人呢？走过去直接告诉他们，确保安全即可… 消息签名 再说消息签名。假设A需要对外发布一条消息“明天去徐家汇吃饭”，并且让接收者能证明这条消息是A发送的。那么A可以用自己的私钥加密消息，然后发布加密后的消息（假设是“ASDFGGHKI”）。这时任何接收者都可以用A的公钥解密消息，问题来了，怎么防止消息本身被篡改过呢？比如B得到的是没篡改过的“ASDFGGHKI”，但C得到的是被篡改过的“DSADFALKDJS”。B用A的公钥解密得到“明天去徐家汇吃饭”，C用A的公钥解密得到“明天去莲花路吃饭”。怎么判断哪个才是A原本发布的消息呢？ 显然，除了解密过程，我们还需要验证过程。如果A发布的消息包括加密后的消息“ASDFGGHKI”作为签名和原本的消息“明天去徐家汇吃饭”，会怎样？假设B得到没篡改过的“ASDFGGHKI明天去徐家汇吃饭”，那么B用A的公钥解密签名得到“明天去徐家汇吃饭”，前后比较一致，说明消息没有被篡改过。假设C得到篡改过的消息“DSADFALKDJS明天去徐家汇吃饭”，C用A的公钥解密签名得到“明天去莲花路吃饭”与后面部分不合，说明消息被篡改。假设D得到篡改过的消息“ASDFGGHKI明天不吃饭”，D解密签名获得“明天去徐家汇吃饭”与后面不合，说明消息被篡改。 看起来没问题了？还是有问题的…前面两个例子都是假设篡改者或者只改签名，或者只改消息。假设篡改者两者都改，有两种情况： 情况一， 假设篡改者希望将消息改为“明天不吃饭”。那么篡改者必须得到“明天不吃饭”被A的私钥加密后的字符串，然后替换掉原来的签名。A的私钥他能拿到吗？不能，所以不可行。 情况二，假设篡改者只是简单地希望破坏掉这条消息，那么他可以把签名部分任意篡改比如改成“SDDF”，然后用A的公钥解密“SDDF”得到比如“呵呵呵”，那么他就能把消息篡改为“SDDF呵呵呵”。接收者并不能判断出这条A发布的消息经过篡改。 好吧，我们只好得出结论，发布消息本身和签名，也不能100%地防止篡改。 怎样才能解决掉上面第二种情况呢？首先，因为A的公钥是公开的，篡改者总是可以根据A的公钥去“解密”一个他给定的字符串。所以问题就出在验证过程上。我们目前的做法是用解密后的数据与消息相比较。所以篡改者可以直接用解密后的字符串替换掉消息。如果我们的验证过程是用解密后的数据与经过不可逆算法处理的消息相比较呢？换句话讲，对消息发布者而言，先用经过不可逆算法处理消息M得到N（消息摘要），再用私钥加密N得到签名，是否可行？ 假设我们有算法S，能够根据输入数据I生成数据O，整个过程不可逆，且I如果不同，则O一定不同。A用算法S处理消息“明天去徐家汇吃饭”，得到消息摘要比如“SDFDFS”，然后用再用私钥加密“SDFDFS”得到比如“SDLKFJDD”作为签名。这时候A发送出去的消息是“SDLKFJDD明天去徐家汇吃饭”。这样能够防篡改吗？ 假设B得到没有篡改过的消息。B先用A的公钥解密签名得到“SDFDFS”，再用S算法处理“明天去徐家汇吃饭”得到消息摘要“SDFDFS”，两者匹配，证明消息没被篡改过。类似的，假设这条消息只是消息本身或者签名被篡改，接收者也能够验证。那么，这个方案能解决掉上面第二种情况吗？ 假设篡改者只是简单地希望破坏掉这条消息，那么他可以把签名部分任意篡改比如改成“SDDF”，然后用A的公钥解密“SDDF”得到比如“呵呵呵”。这时候他需要S的逆算法，通过消息摘要“呵呵呵”来生成出消息比如“这不是真的”，最后将消息篡改为“SDDF这不是真的”。假如S逆算法存在，那么他能够将消息篡改为“SDDF这不是真的”。S逆算法存在吗？不存在，所以篡改者不能这么篡改消息。所以，公私钥+生成消息摘要的不可逆算法，可以防止来自公私钥拥有者的消息被篡改。 总结一下使用数字签名防止消息被篡改的过程：消息发布者使用不可逆算法计算出消息摘要，再用私钥加密消息摘要生成出数字签名，然后将消息与数字签名一起发布；消息接收者使用同样算法根据消息生成出消息摘要，再用消息发布者的公钥解密数字签名并将结果与消息摘要比较，以此验证消息是否被篡改过。 有一点值得一提的是，上面的做法，有个重要的假设：消息接收者都能拿到消息发送者真正的公钥，设想假如某些消息接收者拿到了假的公钥…那么拥有对应假私钥的篡改者就能任意篡改数据了。 消息签名+消息加密 好了，在以上两节的基础上。如果A需要发送消息“明天去徐家汇吃饭”给B，且既需要防截获破解，又需要防篡改。那么结合以上两节的做法，A需要发送这样的信息：“用A的私钥加密（S（明天去徐家汇吃饭））用B的公钥加密（明天去徐家汇吃饭）”。 杂项&#38;参考 RSA算法：一种公开密钥加密算法 SHA算法：一种不可逆的生成报文摘要的哈希算法。 MD5算法：一种不可逆的生成报文摘要的哈希算法。 注：注意在上面防篡改的证明中，用了不严谨的三段论。比如，篡改者需要A的私钥才能生成加密后的数据，篡改者没有A的私钥，所以篡改者不能生成加密后的数据。这是充分条件当作必要条件来用，但是你懂的，写东西很累的，每次都反证必要条件很烦的… 安全，安全…木有100%的安全，假设有黑客能以某种方式破解公开密钥加密算法，或者能破解S算法，或者简单点直接拿了你的私钥，或者让你拿到了假的公钥，那神马都是浮云…有意思的是，正如上面黑体字提到的，利用消息签名防篡改，还是要建立在“消息接收者能拿到消息发送者真正的公钥”这个基础上的。那对消息接收者来说，怎样才能100%安全地拿到这个真正的没被篡改过的公钥呢？…很有意思，这个防篡改安全系统的建立，还是要基于另一个安全假设成立的前提。 To be continued… 本来这篇blog的目的是从理论一直讲到各种应用，比如.NET强命名，授权认证等等。由于我的本事就是把很简单的事情讲的很复杂，所以篇幅很长得分开了…]]></description>
			<content:encoded><![CDATA[<p>前一段做了很多安全相关的东西，简单总结一下。</p>
<h3><strong>Public Key Cryptography</strong></h3>
<p>首先，最基础的，也是目前应用广泛的公私钥加解密理论（<a href="http://zh.wikipedia.org/wiki/%E9%9D%9E%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95">公开密钥加密</a> public key cryptography，又称非对称加密），简单地说指的是公钥和私钥成对被创建，一段信息被公钥加密后只能用对应私钥解密，类似的，一段信息被私钥加密后只能用对应公钥解密。</p>
<p>为什么把这对密钥叫做公钥和私钥呢？假设某人A生成了一对公私钥，公钥是公共的可以告诉其他人的密钥，而私钥是私有的需要保密的的密钥。</p>
<p>这个理论有什么用呢？典型的两个用途，一是<em>消息加密</em>（防截获破解），二是<em>消息签名</em>（防篡改）。</p>
<h3><strong>消息加密</strong></h3>
<p>先说消息加密。假设A需要发送消息给B。那么A可以用B的公钥加密消息，然后将加密后的消息发送给B。B得到加密后的消息，用自己的私钥解密，就能获得这条消息。假设因为传输不安全，加密后的消息被C截获，因为C并没有B的私钥。也就不能解密这条消息。但是这样做并不能防篡改，假设B获得一条声称是发给自己的消息，B并没有办法验证这条消息有没有被篡改。防篡改的内容在下一节讲到。</p>
<p>先暂时跳出公私钥加解密理论的框架。说下<a href="http://zh.wikipedia.org/wiki/%E5%AF%B9%E7%A7%B0%E5%AF%86%E9%92%A5%E5%8A%A0%E5%AF%86">对称加密</a>。对称加密很好理解，一段消息用一个密钥加密过后，也要用同样的密钥解密。回过头看上面的例子，假如A要安全地发送消息给B，或者发给很多人，那假如大家都知道密钥的情况下。A只需要用这个密钥加密消息，然后发送给大家，接收者各自用这个密钥解密。这样在大家都安全地拥有这个密钥的情况下自然不会有问题。不过问题又来了，在密钥被生成出来的时候，如何安全地把这个密钥传送给A以及其他接收者呢？鸡生蛋，蛋生鸡…当然，可以跳出这个系统，怎样安全地把这个密钥传送给A以及其他人呢？走过去直接告诉他们，确保安全即可…</p>
<h3><strong>消息签名</strong></h3>
<p>再说消息签名。假设A需要对外发布一条消息“明天去徐家汇吃饭”，并且让接收者能证明这条消息是A发送的。那么A可以用自己的私钥加密消息，然后发布加密后的消息（假设是“ASDFGGHKI”）。这时任何接收者都可以用A的公钥解密消息，问题来了，怎么防止消息本身被篡改过呢？比如B得到的是没篡改过的“ASDFGGHKI”，但C得到的是被篡改过的“DSADFALKDJS”。B用A的公钥解密得到“明天去徐家汇吃饭”，C用A的公钥解密得到“明天去莲花路吃饭”。怎么判断哪个才是A原本发布的消息呢？</p>
<p>显然，除了<em>解密过程</em>，我们还需要<em>验证过程</em>。如果A发布的消息包括加密后的消息“ASDFGGHKI”作为签名和原本的消息“明天去徐家汇吃饭”，会怎样？假设B得到没篡改过的“ASDFGGHKI明天去徐家汇吃饭”，那么B用A的公钥解密签名得到“明天去徐家汇吃饭”，前后比较一致，说明消息没有被篡改过。假设C得到篡改过的消息“DSADFALKDJS明天去徐家汇吃饭”，C用A的公钥解密签名得到“明天去莲花路吃饭”与后面部分不合，说明消息被篡改。假设D得到篡改过的消息“ASDFGGHKI明天不吃饭”，D解密签名获得“明天去徐家汇吃饭”与后面不合，说明消息被篡改。</p>
<p>看起来没问题了？还是有问题的…前面两个例子都是假设篡改者或者只改签名，或者只改消息。假设篡改者两者都改，有两种情况：</p>
<p>情况一， 假设篡改者希望将消息改为“明天不吃饭”。那么篡改者必须得到“明天不吃饭”被A的私钥加密后的字符串，然后替换掉原来的签名。A的私钥他能拿到吗？不能，所以不可行。</p>
<p>情况二，假设篡改者只是简单地希望破坏掉这条消息，那么他可以把签名部分任意篡改比如改成“SDDF”，然后用A的公钥解密“SDDF”得到比如“呵呵呵”，那么他就能把消息篡改为“SDDF呵呵呵”。接收者并不能判断出这条A发布的消息经过篡改。</p>
<p>好吧，我们只好得出结论，发布消息本身和签名，也不能100%地防止篡改。</p>
<p>怎样才能解决掉上面第二种情况呢？首先，因为A的公钥是公开的，篡改者总是可以根据A的公钥去“解密”一个他给定的字符串。所以问题就出在验证过程上。我们目前的做法是用解密后的数据与消息相比较。所以篡改者可以直接用解密后的字符串替换掉消息。如果我们的验证过程是用解密后的数据与经过不可逆算法处理的消息相比较呢？换句话讲，对消息发布者而言，<strong>先用经过不可逆算法处理消息M得到N（消息摘要），再用私钥加密N得到签名，</strong>是否可行？</p>
<p>假设我们有算法S，能够根据输入数据I生成数据O，整个过程不可逆，且I如果不同，则O一定不同。A用算法S处理消息“明天去徐家汇吃饭”，得到消息摘要比如“SDFDFS”，然后用再用私钥加密“SDFDFS”得到比如“SDLKFJDD”作为签名。这时候A发送出去的消息是“SDLKFJDD明天去徐家汇吃饭”。这样能够防篡改吗？</p>
<p>假设B得到没有篡改过的消息。B先用A的公钥解密签名得到“SDFDFS”，再用S算法处理“明天去徐家汇吃饭”得到消息摘要“SDFDFS”，两者匹配，证明消息没被篡改过。类似的，假设这条消息只是消息本身或者签名被篡改，接收者也能够验证。那么，这个方案能解决掉上面第二种情况吗？</p>
<p>假设篡改者只是简单地希望破坏掉这条消息，那么他可以把签名部分任意篡改比如改成“SDDF”，然后用A的公钥解密“SDDF”得到比如“呵呵呵”。这时候他需要S的逆算法，通过消息摘要“呵呵呵”来生成出消息比如“这不是真的”，最后将消息篡改为“SDDF这不是真的”。假如S逆算法存在，那么他能够将消息篡改为“SDDF这不是真的”。S逆算法存在吗？不存在，所以篡改者不能这么篡改消息。所以，<strong>公私钥+生成消息摘要的不可逆算法，可以防止来自公私钥拥有者的消息被篡改</strong>。</p>
<p>总结一下使用数字签名防止消息被篡改的过程：消息发布者使用不可逆算法计算出消息摘要，再用私钥加密消息摘要生成出数字签名，然后将消息与数字签名一起发布；消息接收者使用同样算法根据消息生成出消息摘要，再用消息发布者的公钥解密数字签名并将结果与消息摘要比较，以此验证消息是否被篡改过。</p>
<p><strong>有一点值得一提的是，上面的做法，有个重要的假设：消息接收者都能拿到消息发送者真正的公钥，设想假如某些消息接收者拿到了假的公钥…那么拥有对应假私钥的篡改者就能任意篡改数据了。</strong></p>
<h3>消息签名+消息加密</h3>
<p>好了，在以上两节的基础上。如果A需要发送消息“明天去徐家汇吃饭”给B，且既需要防截获破解，又需要防篡改。那么结合以上两节的做法，A需要发送这样的信息：“用A的私钥加密（S（明天去徐家汇吃饭））用B的公钥加密（明天去徐家汇吃饭）”。</p>
<h3><strong>杂项&amp;参考</strong></h3>
<p>RSA算法：一种公开密钥加密算法 </p>
<p>SHA算法：一种不可逆的生成报文摘要的哈希算法。</p>
<p>MD5算法：一种不可逆的生成报文摘要的哈希算法。</p>
<p>注：注意在上面防篡改的证明中，用了不严谨的三段论。比如，篡改者需要A的私钥才能生成加密后的数据，篡改者没有A的私钥，所以篡改者不能生成加密后的数据。这是充分条件当作必要条件来用，但是你懂的，写东西很累的，每次都反证必要条件很烦的…</p>
<p>安全，安全…木有100%的安全，假设有黑客能以某种方式破解公开密钥加密算法，或者能破解S算法，或者简单点直接拿了你的私钥，或者让你拿到了假的公钥，那神马都是浮云…有意思的是，正如上面黑体字提到的，利用消息签名防篡改，还是要建立在“消息接收者能拿到消息发送者真正的公钥”这个基础上的。那对消息接收者来说，怎样才能100%安全地拿到这个真正的没被篡改过的公钥呢？…很有意思，这个防篡改安全系统的建立，还是要基于另一个安全假设成立的前提。</p>
<h3><strong>To be continued…</strong></h3>
<p>本来这篇blog的目的是从理论一直讲到各种应用，比如.NET强命名，授权认证等等。由于我的本事就是把很简单的事情讲的很复杂，所以篇幅很长得分开了…</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.pangwa.com/2011/08/26/%e5%ae%89%e5%85%a8%ef%bc%8c%e5%ae%89%e5%85%a81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2011 &#8211; 中</title>
		<link>http://liar.pangwa.com/2011/08/23/2011-%e4%b8%ad/</link>
		<comments>http://liar.pangwa.com/2011/08/23/2011-%e4%b8%ad/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 08:06:39 +0000</pubDate>
		<dc:creator>lie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[扯淡]]></category>
		<category><![CDATA[技术]]></category>

		<guid isPermaLink="false">http://liar.pangwa.com/?p=159</guid>
		<description><![CDATA[好吧，首先，现在已经不是2011年中了，时间嗖嗖的。看pangwa搞的这blog主题不错，杠杠的。 然后，必须要好好搞搞技术了。直接原因是，最近部门考虑重新评估长期技术路线，准备把从前台到后台的整套系统都好好折腾下。于是就有很多的所谓technical workshop / discussion，于是就有很多良性的非良性的技术的非技术的架吵，于是就发现现在忽悠，尤其是在技术方面的忽悠能力下降很多。归根结底，不是忽悠能力的下降，而是技术能力的下降。反思一下，自从从Autodesk跳槽之后，对技术的关注少了很多。前两天买了本久违的程序员，满篇尽是新词语（好吧，各种NoSQL，各种BigTable，各种Cluster），情何以堪啊情何以堪。对新的存储技术、分布式技术的认识，落后了不少。 回头评价一下从Microsoft跳槽Cisco这件事情。在Microsoft做的是Visual Studio里支持Business Application开发的功能和模块。所谓Business Application，无非就是围绕数据、流程、分布式、更上层更傻瓜化（好吧，智能化）的开发。在Cisco做的事情其实某种意义上来说一脉相承，做的就是支持Manufactoring的Business Application / System。从技术上讲，需要处理高并发、海量数据，需要保证接近100%的系统可靠性，需要支持复杂的业务逻辑，需要支持客户端用户开发一些数据处理、测试、仿真的程序和脚本。从行业上讲，和之前做的产品研发不同，而更接近信息系统开发，某种意义上讲也更接近互联网行业。总体来讲，能接触新的技术领域、能接触新的流程，我认为利还是远大于弊的。当然，毫无疑问，频繁跳槽是不对的。。。 好了，CHEER UP!]]></description>
			<content:encoded><![CDATA[<p>好吧，首先，现在已经不是2011年中了，时间嗖嗖的。看pangwa搞的这blog主题不错，杠杠的。</p>
<p>然后，必须要好好搞搞技术了。直接原因是，最近部门考虑重新评估长期技术路线，准备把从前台到后台的整套系统都好好折腾下。于是就有很多的所谓technical workshop / discussion，于是就有很多良性的非良性的技术的非技术的架吵，于是就发现现在忽悠，尤其是在技术方面的忽悠能力下降很多。归根结底，不是忽悠能力的下降，而是技术能力的下降。反思一下，自从从Autodesk跳槽之后，对技术的关注少了很多。前两天买了本久违的程序员，满篇尽是新词语（好吧，各种NoSQL，各种BigTable，各种Cluster），情何以堪啊情何以堪。对新的存储技术、分布式技术的认识，落后了不少。</p>
<p>回头评价一下从Microsoft跳槽Cisco这件事情。在Microsoft做的是Visual Studio里支持Business Application开发的功能和模块。所谓Business Application，无非就是围绕数据、流程、分布式、更上层更傻瓜化（好吧，智能化）的开发。在Cisco做的事情其实某种意义上来说一脉相承，做的就是支持Manufactoring的Business Application / System。从技术上讲，需要处理高并发、海量数据，需要保证接近100%的系统可靠性，需要支持复杂的业务逻辑，需要支持客户端用户开发一些数据处理、测试、仿真的程序和脚本。从行业上讲，和之前做的产品研发不同，而更接近信息系统开发，某种意义上讲也更接近互联网行业。总体来讲，能接触新的技术领域、能接触新的流程，我认为利还是远大于弊的。当然，毫无疑问，频繁跳槽是不对的。。。</p>
<p>好了，CHEER UP!</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.pangwa.com/2011/08/23/2011-%e4%b8%ad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2011 &#8211; 起</title>
		<link>http://liar.pangwa.com/2011/02/09/2011-%e8%b5%b7/</link>
		<comments>http://liar.pangwa.com/2011/02/09/2011-%e8%b5%b7/#comments</comments>
		<pubDate>Tue, 08 Feb 2011 19:10:17 +0000</pubDate>
		<dc:creator>lie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://liar.pangwa.com/?p=155</guid>
		<description><![CDATA[又很久没写blog了 &#8211; 上大学以来，扯淡、写字、作文的频率和水平都直线下降。。。目前看来也没有止住的趋势。 看看大家的blog，发现竟然没几个童鞋按惯例写了2010总结。好吧，我来写个先：2010是比较堕落和诡异的一年，堕落在上半年玩桌游、下半年玩网游，诡异在比较被动的跳槽。整体来说是没有什么进步的一年。非得要说有，那就是新工作工作内容和角色的不同，也算是好事。 再说2011的计划： - （此处省略n个字） - 少宅多动 - 搞搞小副业 - 跟风学习点经济类知识 - 好好工作&#8230; - 多搞点杂事 &#8211; 看杂书、聊QQ之类 - 继续修炼&#8230;尤其需要牢记diversity的原则&#8230;不能自负 希望能达成几个&#8230; 励志一下，几年前和pangwa老三懂懂都比较认真地讨论过人生的意义。最后让我觉得满意并且不再纠结的说法是子曾经曰过的：志于道，据于德，依于仁，游于艺。好吧，其实我只是念叨着满足一下形而上的理论，并不能真正理解&#8230;]]></description>
			<content:encoded><![CDATA[<p>又很久没写blog了 &#8211; 上大学以来，扯淡、写字、作文的频率和水平都直线下降。。。目前看来也没有止住的趋势。</p>
<p>看看大家的blog，发现竟然没几个童鞋按惯例写了2010总结。好吧，我来写个先：2010是比较堕落和诡异的一年，堕落在上半年玩桌游、下半年玩网游，诡异在比较被动的跳槽。整体来说是没有什么进步的一年。非得要说有，那就是新工作工作内容和角色的不同，也算是好事。</p>
<p>再说2011的计划：</p>
<p>- （此处省略n个字）<br />
- 少宅多动<br />
- 搞搞小副业<br />
- 跟风学习点经济类知识<br />
- 好好工作&#8230;<br />
- 多搞点杂事 &#8211; 看杂书、聊QQ之类<br />
- 继续修炼&#8230;尤其需要牢记diversity的原则&#8230;不能自负</p>
<p>希望能达成几个&#8230;</p>
<p>励志一下，几年前和pangwa老三懂懂都比较认真地讨论过人生的意义。最后让我觉得满意并且不再纠结的说法是子曾经曰过的：志于道，据于德，依于仁，游于艺。好吧，其实我只是念叨着满足一下形而上的理论，并不能真正理解&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.pangwa.com/2011/02/09/2011-%e8%b5%b7/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>冰与火之歌</title>
		<link>http://liar.pangwa.com/2010/03/27/%e5%86%b0%e4%b8%8e%e7%81%ab%e4%b9%8b%e6%ad%8c/</link>
		<comments>http://liar.pangwa.com/2010/03/27/%e5%86%b0%e4%b8%8e%e7%81%ab%e4%b9%8b%e6%ad%8c/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 11:44:26 +0000</pubDate>
		<dc:creator>lie</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[看书]]></category>

		<guid isPermaLink="false">http://liar.pangwa.com/2010/03/27/%e5%86%b0%e4%b8%8e%e7%81%ab%e4%b9%8b%e6%ad%8c/</guid>
		<description><![CDATA[话说看书 &#8211; 小时候看了很多杂书，上大学过后基本都看技术书，工作了过后连技术书也不怎么看了…空虚了看看yy小说，看完过后更加空虚 –_- 在懂懂 / pangwa同学的影响下有时也看点树立正确人生观世界观的nb书。偶尔在枕头旁边放两本书，也都是看过的三国演义之类的。至于武侠，金古两位大侠的书都翻烂了… 上回说到，最近在看叫冰与火之歌的系列小说。还没出完，目前有四本，据说七本结束。中文版翻译的相当好。书接上回，这回说冰与火之歌如何如何好。 本书作为魔戒之后奇幻文学的扛鼎之作，得过XX、YY、ZZ等很多奖或者提名，销量突破NN册…Zzzzzzzz 全是废话。简单地说，冰与火之歌这好，那也好 - 绝对的少儿不宜，很黄很暴力，很很黑暗。有赤裸裸的色情描写，和更加赤裸裸的暴力描写。不是“大喝一声，连头带肩，斩为两段”，也不是“左掌一圈一引，右掌一招XXXX，YY骨断筋折”，而是类似“深红的血和脑浆从断口中不断涌出，半边头颅滚到一边，XXX吩咐侍从把血肉沥上焦油，插到城墙的旗杆上，让乌鸦一丝一丝地啄食”。除开暴力和色情，黑暗的描写、残酷的剧情贯穿始终，相当难能可贵… 没有真正意义上的英雄，鲜有所谓的正面/反面人物。比如魔戒里面有明显的大反派Sauron，正面角色Gandalf；三国有红脸关羽、白脸曹操。冰与火之歌里的人物绝大多数都是复杂的、灰色的、多面性的，有自己的经历、性格和立场。这些灰色人物，他们的人性、冲突和感情，是这个黑暗世界里耀眼的闪光和希望。 没有主角，没有主线，没有目录。每一章节都是从不同人物的角度去写，写发生在同一个世界、不同时间不同地点的事情。零碎的片段组成整部书的剧情。如果非得说有主角，那主角就是描写、出现的比较多的那些。非得说有主线，主线就是这个架空世界的历史。不过虽然人物繁多，特点却非常鲜明。人物多到根本不可能能记住所有名字（而且外国佬的名字本来就难记…），但是总能记住那些人。 奇幻成分很少。魔戒是一个低魔的世界，以至于电影里Gandalf从来就不会用什么火球术之类的法术，法杖主要用来当手电筒，经常需要挽袖子抄家伙带头上阵砍人。冰火是更低魔的世界，以至于有时候我觉得看的是架空历史小说…穿插出现的奇幻色彩，也让人觉得很自然很真实。 我看到冰原狼的旗帜飘扬在临冬城的废墟上，告诉人们“凛冬将至”。 我听到长城上的黑衣兄弟 &#8211; 私生子、强奸犯、胆小鬼、杀人犯们的誓言：“长夜将至，我从今开始守望，至死方休。我将不娶妻、不封地、不生子。我将不戴宝冠，不争荣宠。我将尽忠职守，生死於斯。我是黑暗中的利剑，长城中的守卫。我是抵御寒冷的烈燄，破晓时分的光线，唤醒死者的号角，守护王国的铁卫。我将生命与荣耀献给守夜人，今夜如此，夜夜皆然。” 我还记得女野人临死前对背叛者的低语：“琼恩·雪诺，你什么都不懂。”]]></description>
			<content:encoded><![CDATA[<p>话说看书 &#8211; 小时候看了很多杂书，上大学过后基本都看技术书，工作了过后连技术书也不怎么看了…空虚了看看yy小说，看完过后更加空虚 –_- 在懂懂 / pangwa同学的影响下有时也看点树立正确人生观世界观的nb书。偶尔在枕头旁边放两本书，也都是看过的三国演义之类的。至于武侠，金古两位大侠的书都翻烂了…</p>
<p>上回说到，最近在看叫冰与火之歌的系列小说。还没出完，目前有四本，据说七本结束。中文版翻译的相当好。书接上回，这回说冰与火之歌如何如何好。</p>
<p>本书作为魔戒之后奇幻文学的扛鼎之作，得过XX、YY、ZZ等很多奖或者提名，销量突破NN册…Zzzzzzzz 全是废话。简单地说，冰与火之歌这好，那也好 -</p>
<p>绝对的少儿不宜，很黄很暴力，很很黑暗。有赤裸裸的色情描写，和更加赤裸裸的暴力描写。不是“大喝一声，连头带肩，斩为两段”，也不是“左掌一圈一引，右掌一招XXXX，YY骨断筋折”，而是类似“深红的血和脑浆从断口中不断涌出，半边头颅滚到一边，XXX吩咐侍从把血肉沥上焦油，插到城墙的旗杆上，让乌鸦一丝一丝地啄食”。除开暴力和色情，黑暗的描写、残酷的剧情贯穿始终，相当难能可贵…</p>
<p>没有真正意义上的英雄，鲜有所谓的正面/反面人物。比如魔戒里面有明显的大反派Sauron，正面角色Gandalf；三国有红脸关羽、白脸曹操。冰与火之歌里的人物绝大多数都是复杂的、灰色的、多面性的，有自己的经历、性格和立场。这些灰色人物，他们的人性、冲突和感情，是这个黑暗世界里耀眼的闪光和希望。</p>
<p>没有主角，没有主线，没有目录。每一章节都是从不同人物的角度去写，写发生在同一个世界、不同时间不同地点的事情。零碎的片段组成整部书的剧情。如果非得说有主角，那主角就是描写、出现的比较多的那些。非得说有主线，主线就是这个架空世界的历史。不过虽然人物繁多，特点却非常鲜明。人物多到根本不可能能记住所有名字（而且外国佬的名字本来就难记…），但是总能记住那些人。</p>
<p>奇幻成分很少。魔戒是一个低魔的世界，以至于电影里Gandalf从来就不会用什么火球术之类的法术，法杖主要用来当手电筒，经常需要挽袖子抄家伙带头上阵砍人。冰火是更低魔的世界，以至于有时候我觉得看的是架空历史小说…穿插出现的奇幻色彩，也让人觉得很自然很真实。</p>
<p><em>我看到冰原狼的旗帜飘扬在临冬城的废墟上，告诉人们“凛冬将至”。</em></p>
<p><em>我听到长城上的黑衣兄弟 &#8211; 私生子、强奸犯、胆小鬼、杀人犯们的誓言：“长夜将至，我从今开始守望，至死方休。我将不娶妻、不封地、不生子。我将不戴宝冠，不争荣宠。我将尽忠职守，生死於斯。我是黑暗中的利剑，长城中的守卫。我是抵御寒冷的烈燄，破晓时分的光线，唤醒死者的号角，守护王国的铁卫。我将生命与荣耀献给守夜人，今夜如此，夜夜皆然。”</em></p>
<p><em>我还记得女野人临死前对背叛者的低语：“琼恩·雪诺，你什么都不懂。”</em></p>
]]></content:encoded>
			<wfw:commentRss>http://liar.pangwa.com/2010/03/27/%e5%86%b0%e4%b8%8e%e7%81%ab%e4%b9%8b%e6%ad%8c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

