<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-伯乐共勉</title><link>http://www.cnblogs.com/qiubole/</link><description>讨论。NET专区</description><language>zh-cn</language><lastBuildDate>Sun, 07 Sep 2008 07:43:27 GMT</lastBuildDate><pubDate>Sun, 07 Sep 2008 07:43:27 GMT</pubDate><ttl>60</ttl><item><title>乱码大全</title><link>http://www.cnblogs.com/qiubole/archive/2008/08/26/1276703.html</link><dc:creator>伯乐共勉</dc:creator><author>伯乐共勉</author><pubDate>Tue, 26 Aug 2008 06:52:00 GMT</pubDate><guid>http://www.cnblogs.com/qiubole/archive/2008/08/26/1276703.html</guid><wfw:comment>http://www.cnblogs.com/qiubole/comments/1276703.html</wfw:comment><comments>http://www.cnblogs.com/qiubole/archive/2008/08/26/1276703.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/qiubole/comments/commentRss/1276703.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/qiubole/services/trackbacks/1276703.html</trackback:ping><description><![CDATA[摘要: 发信人: bluesea (蓝海), 信区: Internet标 题: 乱码大全(1)──综述(第二版)发信站: BBS 水木清华站 (Sun Feb 15 15:54:37 1998)乱码大全(1)──综述(第二版)本文第一版本于98年2月3日发于本板。这一版本修改了原文中关于字符集的一些不确切的说法。&#8220;乱码大全&#8221;，作者：bluesea，水木清华BBS成员。欢迎在 BBS&nbsp;&nbsp;<a href='http://www.cnblogs.com/qiubole/archive/2008/08/26/1276703.html'>阅读全文</a><img src ="http://www.cnblogs.com/qiubole/aggbug/1276703.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42132/" target="_blank">[新闻]Google 10周岁生日</a>]]></description></item><item><title>给老板娘的一封信</title><link>http://www.cnblogs.com/qiubole/archive/2008/08/13/1266869.html</link><dc:creator>伯乐共勉</dc:creator><author>伯乐共勉</author><pubDate>Wed, 13 Aug 2008 06:14:00 GMT</pubDate><guid>http://www.cnblogs.com/qiubole/archive/2008/08/13/1266869.html</guid><wfw:comment>http://www.cnblogs.com/qiubole/comments/1266869.html</wfw:comment><comments>http://www.cnblogs.com/qiubole/archive/2008/08/13/1266869.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/qiubole/comments/commentRss/1266869.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/qiubole/services/trackbacks/1266869.html</trackback:ping><description><![CDATA[<p><font face="Verdana">尊敬的老板娘<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;首先请原谅我用老板娘这个称呼，这让人容易联想古代参政的后妃，但我确实找不到更合适的字眼，上次有个朋友建议我尊称您为副总经理，当我把您雷厉风行的工作作风和不拘一格的工作态度以及勇于突破工作流程及制度的方式告诉他之后，他也觉的您不应该只是个副总经理。可惜咱们国家太看重资历，否则，我一定推举您去做总理，总理和总经理其实也就差一个字嘛，您可以在这么小的一个行业里面获取如此丰厚的利润，并时时以自己的成就告诫我们这些不思进取的员工，说真的，我在内心里崇拜您。每天上班下班都要问候一次您家里所有的女性</font></p>
<p><font face="Verdana">&nbsp;&nbsp;能收到您这样一封对问题一针见血的邮件，内心可是相当激动。在过去，您都是用最直接的方式最快的要求我们发现问题，解决问题。今天能用文字的方式指导我们，让我们能时时看到它，时时提醒自己范了错误，那是多么的难得，不像我们，有屁大的事，都要发个邮件，写个便签之类的。<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;对您的邮件，我细读了好几次，请教了好几个古代文学，现代文学专业的朋友，才明白文言文与现代都话可以这么奇妙的组合。在以前，我竟然都不知道邮件里面可以用中英文，拼音，家乡话，通假字。憋足的我还经常去查字典，说起来太丢人了。通假字这种高深的方式，现在还不会用。<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;在看完所有的内容之后，其实我还是有话要说的，那就是和我共同搭挡的另一个助理，虽然说在工作岗位上是和我平级的，但她作为您的亲戚，时时在家能受到您的熏陶，这次工作出了点问题，您直接责问我就好了，没有必要把邮件也发给她，其实我已经很习惯了，您的老公，您的大哥，还有您这位亲戚，以及一些我不太认识的亲戚。其实平时就有对我这种责问的训练，我真的已经习惯了。以前报表这种杂事都是我做的，您亲戚都是负责领导方向上的事，这次您让这位亲戚百忙之中抽空帮我，我竟然没有注意她不屑这方面，出了这么大的问题，事后还没有反省，确实是不应该。有句话形容的很贴切，虽然现在的人都不用了，但我还是想说&#8216;小的该死，都是小的不是&#8217;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;对于这次出的问题，处理方式上我其实一直都在学习您，那个客户拖欠了我们邮寄的费用，虽然说只有几十块钱，但毕竟也是人民的血汗钱，我还顾及自己的淑女形象，慢条斯理的和他讲道理，真是不该，现在我想起那次您处理一个楼上的客户，打电话过程中电话挂了楼上那人还能听到您的教诲，后来他再也没有欠我们什么钱了，什么是雷厉风行，这就是。当然，您为了公司的利益，让我个人掏这些钱，我也能理解，但我好久没发工资了，为什么不能从里面扣。而且好像合同不是我签的，我只是一个跟班啊。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;我朋友和我说，自从我进了咱们公司，好像懂的特别多了，其实那还不是您的功劳。进公司之后，为了公司的日常工作，大的方面我学习了会计，合理避税，人事管理，业绩考核，流程制订，业务跟单，追款，商务事宜，做对账单等等。小的方面就更多了，比如修网络，扫地，倒茶，看门，擦桌子，接电话啥的，您知道吗，这些以前我都是不会的。<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;我对我朋友说懂这么多的时候，他竟然还笨得以为我都是在上班的时候做的，他这人，太不懂得合理利用时间了，上班当然有上班该做的事啊，有些事情，当然得在下班的时候做。您不是说了吗，为了社会主义的振兴，每天加班当然是应该的。<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;我不但学会了这么多的东西，还广交人缘，公司有些东西不好处理，您就主动让我发挥自己的人脉，请朋友把这些问题搞定。要不，这样，又省了钱，又拉近了关系。还有一点好处就是，以前一些对我有意思的朋友，现在见我就躲，呵呵，我也不用为这烦恼了<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;其实说这么多已经没用了，我那些不思进取的朋友都劝我离开公司，本来我也不为所动的，想想，我在公司的生活多充实啊，而且公司欠我们的薪水也不多，听您的描述，若干年后公司上市了，还会给我们分红。<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;不过，我确实没钱用了，另一家公司肯给我的工资，比您这要高很多，比整个深圳市的最低工资还要高。想想我很难过，您经常和我说的不要看眼前利益的话我都理解不了，看来我天生做不了大事了<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;我就只给你回邮件请辞了，不敢当面和你说，上次一个同事为次还赔了培训费用的事我还没忘记。<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;工资我就不要了，祝您生意兴隆，再次问候您家里的所有女性，哦，对了，上次税务局的朋友和劳动局的朋友说举报有奖，我想去试试，希望能补回我的亏空。<br />
</font></p>
<img src ="http://www.cnblogs.com/qiubole/aggbug/1266869.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42131/" target="_blank">[新闻]祝Google 10周岁生日快乐</a>]]></description></item><item><title>一年前的工作日记</title><link>http://www.cnblogs.com/qiubole/archive/2008/08/13/1266620.html</link><dc:creator>伯乐共勉</dc:creator><author>伯乐共勉</author><pubDate>Wed, 13 Aug 2008 02:57:00 GMT</pubDate><guid>http://www.cnblogs.com/qiubole/archive/2008/08/13/1266620.html</guid><wfw:comment>http://www.cnblogs.com/qiubole/comments/1266620.html</wfw:comment><comments>http://www.cnblogs.com/qiubole/archive/2008/08/13/1266620.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/qiubole/comments/commentRss/1266620.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/qiubole/services/trackbacks/1266620.html</trackback:ping><description><![CDATA[<font face="Verdana">
<p><font face="Verdana">2007-9-24<br />
&nbsp; 今天是进公司第一天，上午，办完了手续就已经到了十点多钟了，接着和部门的几个主要负责人见了一面，了解了当前需要做的主要工作。<br />
&nbsp; 当然，不管进哪个公司 ，第一天总是在安装系统之中度过的，这台电脑好郁闷，配置不差，但是执行的速度真是叫做一个慢，而且这里的网速确实太差了，唉。<br />
&nbsp; 一整天，连个OFFICE2007都没有装进去。<br />
&nbsp; 不过，还好将DELPHI以及其所需要要的所有的东西都装进去了，然后进行了编译，基本上没有啥问题<br />
&nbsp; <br />
&nbsp; <br />
&nbsp; 下午大部分的时间都在查看GTMAIL的源代码，当然，重点是放在如何将现有的数据库处理部分进行改良。现在漫无目的的看是不行的。<br />
&nbsp; 从向方方了解的情况来看，可能问题主要是出在数据库引擎那一块，对他所认为将DAO修改成ADO，以此来避免出现数据库损坏的，个人不是非常的认同。<br />
&nbsp; <br />
2007-9-25<br />
&nbsp; 今天是进公司的第一天，计划从今天开始，花一天的时间将数据库所有相关的内容都整理一下，然后再决定如何去处理它，当前要处理的方式可能主要就是两种了。<br />
&nbsp; 一种是根据它现有的架构，看哪些不符合，不符合的内容就进行更改，原来它里面所涉及的SQLITE中的内容，连编译都通不如，估计只是写了一部分的接口，而没有深入进行下去。<br />
&nbsp; 另一种方式就是将现有的与数据库相关的业务逻辑分离出来，这个工作量就非常大了。但是，如果设计处理得好，在下一个版本中就可以通用了。<br />
&nbsp; <br />
&nbsp; 比如：通讯录，它与数据库交互的时候，肯定不应该是直接在通讯录那个窗口中直接操作数据库，现有的提供一大堆的方法其实也是不可行的，可读性和可扩展性都非常的差。<br />
&nbsp; 最好是采用简单而又实用的MVC方式了，当然，在支持多数据库类型的时候，再接着采用类工厂的创建模式，对于可扩展性上来讲是非常适合的。<br />
&nbsp; <br />
&nbsp; 接下来要进行代码的研读，从读代码的方向上，看有以下几种方法，一是根据数据库为方向，看是它利用数据库存储了哪些内容，然后找到这些内容，看它与IO的处理方面。<br />
&nbsp; 另外，就是逐个读了，当然，这种方式真是太不可取了。</font></p>
<p><font face="Verdana">&nbsp; 上午与曾进行了一次通话,通过与他的对话中,也能够看出来,他也是急切希望改善数据存储这一块的,之前他也看过SQLITE, 这一次决定我和他一起来处理这个,不过,<br />
&nbsp; 我对于他发给我的那一套控件却不是非常感兴趣,因为那个控件真是太大了,如果像这样下去的话,我们的系统那还得了.<br />
&nbsp; <br />
&nbsp; 他对他的系统改进存储这一块的内容还是充满信心的,当然,这系统从头到尾都是他开发的,虽然说用了N多的控件啥的,但是,从他的用户量上看还是非常不错的,看看5DMAIL中<br />
&nbsp; 能把他的EMAIL放上去,看来这家伙也是有一定的水平的.<br />
&nbsp; <br />
&nbsp; 线程这一块的处理,现在还没有时间看,如果有时间肯定是要看一看的了.<br />
&nbsp; <br />
&nbsp; 今天下午先看一下他推荐给我的控件,再比较一下之前那一套控件,看那套控件是否能支持最新版本的SQLITE,如果不能支持的话,那就只能使用他现在推荐给予我的这一套了.<br />
&nbsp; <br />
&nbsp; 其实,我更多的还是想使用原生的DLL接口,虽然用起来没有组件化的类那么方便使用,但是我觉得那样的放,自己的掌控能力会非常强,也不至于出现控件中有一大堆问题,自己却无法解决的.<br />
&nbsp; </font></p>
<p><font face="Verdana">&nbsp; 接下去需要了解的方向比较多,比如存储,IO,多线程,SOCKET等等,这一切都是我以前比较弱的,虽然在面向对象的编程上面,有着一定的功底,但这也不一定意味着就能够在这个GTMAIL的工作中大展拳脚步.<br />
&nbsp; <br />
&nbsp; 下一个系统的开发需要的东西实在是太多了,界面,存储,多用户,网络连接,加密,协议的处理,现在这个系统还不支持HTTP代理,还不支持IMAP协议,还不支持各种各样的防止垃圾邮件的办法.<br />
&nbsp; </font></p>
<p><font face="Verdana">对于下午的计划,还是要先定一下,当然是先花上几个小时,与小曾一起探讨一下改成SQLITE的总题,然后向他讨教一下,这里面的一些线程的处理方法,以及为什么不直接使用INDY,而要自己封装一大堆栈的东西.<br />
另外,要就DM中,一些用户的问题,再次提出.</font></p>
<font face="Verdana">
<p><br />
2007-9-26<br />
&nbsp; 今天在公司的主要的工作，还是接着昨天对于SQLITE的修改，但改着改着，发现问题越来越多，本来，是简单的进行修改一下相关的SQL语句就行，后来发现，SQLITE我使用的这一套控件，竟然不支持直接<br />
&nbsp; 使用QUERY的更新，需要拼SQL语句，本来拼SQL语句也没有啥大不了的，但实际工作中，还发现虽然使用自己拼写的SQL语句，对但于一些比如BLOG字段就没有任何的办法了。<br />
&nbsp; 看来，考虑一下，是全部改成TABLE，还是用函数级别的类型进行处理。<br />
&nbsp; <br />
&nbsp; 做了一个上午，真是不知道做了些什么东西，如果按照这个进度下去的话，估计够呛了，难道晚上需要加班吗，不是吧，对于线程，数据库的处理，我看本来是没有什么大的问题的，看来还是需要多多进行沟通。<br />
&nbsp; <br />
&nbsp; 今天上午没有碰上小曾，下午看一看，如果下午他在的话，那么就这一些相关遇上的问题向他进行请教。 这些事情怎么要搞得这么复杂呢。<br />
&nbsp; <br />
&nbsp; 按照原定的计划，这一周肯定是要搞定的，否则，面上就不好过了，宋总可是对我抱有很大的希望，如果这个时候不拿出一点成绩来，危险了。<br />
&nbsp; <br />
&nbsp; 按照原定的计划，这一周肯定是要搞定的，否则，面上就不好过了，宋总可是对我抱有很大的希望，如果这个时候不拿出一点成绩业不，人顺炙我看来本来是没有什么原子核总是我，看来做了一个上午，真是不知道做了些什么东西。<br />
&nbsp; <br />
&nbsp; 下午，和方方一起讨论了一下，发现，用一个新型的控件时，我竟然把数据库弄错了，一个0字节的数据库，真是汗啊。<br />
&nbsp; <br />
2007-09-27<br />
&nbsp; 又到了一天一次的写日记的时候了，不知道为什么，今天办公室比较吵，人来人往的，估计是领导都不在的原因吧。<br />
&nbsp; 今天真的没有做什么事情，上午一不小心把那个BLOB字段的问题解决完之后，大概试了几下，感觉没有啥问题，然后就想尽办法让GTMAIL不断地收文件。<br />
&nbsp; 收了大概五百封邮件，也没有发现什么问题。<br />
&nbsp; <br />
&nbsp; 明天处理一下，就可以交给测试组的人去处理了，如果没有啥大的问题，我想，就可以考虑如何将以往的数据转向SQLITE了<br />
&nbsp; <br />
&nbsp; <br />
&nbsp; <br />
2007-09-28<br />
&nbsp; 今天是来公司的第五天了，前四天还真是不知道怎么过去的，只是感觉做了一些事情，又好像没有真的做什么，一直在为SQLITE数据库而烦恼，而昨天，为了写一个EMAIL服务器<br />
&nbsp; 又让我烦恼了好久，真不知道POP3的协议解析这么麻烦，想装一个网络嗅探器，竟然把计算机给装死了。<br />
&nbsp; 要是重装系统就真是太郁闷了，还好昨天早上一来就做了个GHOST备份，真是天助我也，今天顺便杀杀毒，如果真的不行、<br />
&nbsp; <br />
&nbsp; 只能抽空来安装一下操作系统了。<br />
&nbsp; <br />
2007-09-29<br />
&nbsp; 今天将数据库的大部分内容都过了一遍，准备交给测试组，但测试组说任务实在是太忙了，估计要排到下个月的十号。<br />
&nbsp; 而且，他们要求我将现有的所有的BUG都改一次，还要进行什么评估之类的。<br />
&nbsp; 唉，本来想让他们测试的只不过就是数据库这一块，如果数据库这一块没有问题了，那么才可能进行评估，先让我们进行评估选择哪一个数据库的版本，这真是让我感觉有些本末倒置了。</p>
<p>&nbsp; 下午看了一下CQ中的一些BUG。才发现，自己在数据库压缩这一块的工作，竟然还没有开始做。花了两个多小时，才找到相关的一些资料，原来是使用一个VACUUM的指令。<br />
&nbsp; 但是使用了这个指令之后，将会带来更多的问题，比如，当前所有的数据库访问竟然会出问题，而且，不在程序里面进行压缩，而在外面使用SQLITEADMIN进行压缩，也会出现相关的问题。<br />
&nbsp; 这真是让人郁闷了，所以，这一块的内容只能等到以后对SQLITE比较熟悉之后，再进行开始了，我怀疑SQLITE中的一些连接可以有某些属笥可以设置的吧。<br />
&nbsp; <br />
&nbsp; 感觉工作效率很低，而且对代码的了解太少了，十一肯定是要好好地看一些源码了。&nbsp; <br />
2007-09-30&nbsp; <br />
&nbsp; 今天的工作安排，现在还没有想好，不过，我想将拆分邮件这一块好好地处理一下，是肯定的，最好的办法，就是在系统中，根本就不要显示拆分中待发送的邮件，不知道这一块的改动有多大。<br />
&nbsp; 先按现有的一些方法吧，然后将其中可能有问题的地方，防止出现误操作。<br />
&nbsp; 明天就要放假了，说实话，其实心里没啥激动的，十一还不知道怎么过呢，唉<br />
&nbsp; </p>
<p>周工作总结：<br />
&nbsp; 刚进公司的一周，前几天一直在摸索如何将数据库改成SQLITE，后面几天，主要就是测试一下，然后熟悉一下源代码，同时，将现在CQ中的一些BUG进行修改，<br />
&nbsp; 感觉源码写得还是非常不错的，而且在多线程的模式下，分离处理得还是不错，<br />
&nbsp; 与陈经理沟通了一下，他觉得下一步的工作，是需要将界面与处理逻辑相分离，最好是将数据库独立出来，然后分离一下。而宋总的主要想法好像竟然是要重新做一个系统。<br />
&nbsp; 然后把界面处理。同时要将一些认为没有用的功能进行去除。<br />
&nbsp; <br />
&nbsp; 这部分的工作量肯定是比较大的。而且，一个处理不好，很容易出现一些BUG气死人的情况。<br />
&nbsp; <br />
&nbsp; <br />
2007-10-8<br />
&nbsp; 今天主要是把安装包熟悉了一下。然后，针对SQLITE版本的，定制了一下安装包，做安装包的时候，没有发现什么问题，当然，最终还是把安装打好包之后，准备交给测试组，由他们去安排测试 。</p>
<p>2007-10-9<br />
&nbsp; 今天主要的任务还是熟悉代码，很幸运的是，今天竟然把一直困绕的邮件列表的刷新问题解决了。<br />
&nbsp; 今天还更改了几个问题，一个是在压缩之后，强制定要求应用程序关闭。<br />
&nbsp; 另一个是联系人中，如果EMAIL输入错误，同时，又在关闭的时候选择退出的话，提示信息有误，这个也已经更改过来了。<br />
&nbsp; <br />
&nbsp; 系统的启动速度还是比较慢，看来还是需要把这个改成多线程来处理了。<br />
&nbsp; <br />
&nbsp; 大概看了一下系统的加密这一块的处理，感觉，是不是把简单的东西写得太复杂了。</p>
<p>2007-10-10<br />
&nbsp; 今天真是没有什么计划，也没有什么目标，还是想办法边改BUG边熟悉源代码吧，源代码总共有13万多行，真是会看死人<br />
&nbsp; 对于系统的一些协议也不是非常的熟悉，什么MIME结构，POP3，SMTP，IMAP等只是有一个大概的了解。没有非常深入细致的处理。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp; 下午麦克给我打了个电话，意思就是想让我尽量进行重写GTMAIL的代码，这个重写的工作量真是很大，我准备先出一个方案给他<br />
&nbsp; 与方方进行讨论之后，他给我的意见是，先给麦克，宋总，陈经理提解决方案，给他们陈述一下利害关系，由他们进行决定，不管是如何<br />
&nbsp; 最少也要进行一系列的改动过程。&nbsp; <br />
&nbsp; <br />
&nbsp; 它强任它强，清风拂山岗，它横任它横，明月照大江。<br />
&nbsp; <br />
2007-10-11&nbsp; <br />
&nbsp; 上午还要一上午的时候，写了一下简单的方案，也定义了一下新系统的分层结构，对于这种结构，其实早就想好了的。<br />
&nbsp; 在原来的DM之中其实也有这种结构，只是在这种结构之中，与现有的其它的层有很多的冗余。<br />
&nbsp; 也就是分层的结构有点小问题，之间的接口描述不清晰。<br />
&nbsp; <br />
&nbsp; 下午，宋总找我，讨论了一下关于设备管理系统的大致构想，他的意思，要么请人做，要么外包，他的想法之中，想让我找朋友来做的意思居多，那么需求分析这一块<br />
&nbsp; 的任务肯定是分给我了，而也没有给我定义具体的工作计划，不知道是想让我现在就开始做呢，还是想如何，对于这种需求分析，其实是蛮花时间的，需要和各个部门进行沟通<br />
&nbsp; 不过，这样也好，刚好熟悉一下公司的相关部门的工作职责，以及对这个软件的功能的需求。<br />
&nbsp; <br />
</font></p>
</font>
<img src ="http://www.cnblogs.com/qiubole/aggbug/1266620.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42131/" target="_blank">[新闻]祝Google 10周岁生日快乐</a>]]></description></item><item><title>预测中国主要赛事夺金亮点 按日程</title><link>http://www.cnblogs.com/qiubole/archive/2008/08/12/1265618.html</link><dc:creator>伯乐共勉</dc:creator><author>伯乐共勉</author><pubDate>Tue, 12 Aug 2008 01:01:00 GMT</pubDate><guid>http://www.cnblogs.com/qiubole/archive/2008/08/12/1265618.html</guid><wfw:comment>http://www.cnblogs.com/qiubole/comments/1265618.html</wfw:comment><comments>http://www.cnblogs.com/qiubole/archive/2008/08/12/1265618.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/qiubole/comments/commentRss/1265618.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/qiubole/services/trackbacks/1265618.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p><font face="Verdana">8月9日　第壹天 <br />
&nbsp;&nbsp;&nbsp; 金牌数：7枚&nbsp;&nbsp;&nbsp; 金牌分布：自行车（1）、击剑（1）、举重（1）、柔道（2）、射击（2）&nbsp;&nbsp;&nbsp; 看点综述：经过6、7两日的足球预赛和8日的开幕式，北京奥运会在这天进入正式比赛的第一天，首枚奥运金牌花落谁家无疑是今天比赛最大的看点。上午10时30分，女子10米气步枪决赛将在北京射击馆举行，几乎与此同时女子举重48公斤级最后决赛也将开始。此外，篮球和排球两个大项的小组赛都将在今天开打。&nbsp;&nbsp;&nbsp; 中国争金点：4年前为中国队夺得首金的杜丽将再次代表中国队冲击北京奥运会的第一枚金牌，而第三次参加奥运会的名将赵颖慧将为中国队的&#8220;首金之争&#8221;加上双保险。上届奥运会银牌得主中国第一女剑客谭雪将参加女子佩剑的决赛，王明娟、杨炼、陈燮霞中的一人将代表中国队参加女子举重48公斤级的决赛，旨在收复4年前中国队丢失的唯一一枚女举金牌。<br />
8月10日　第贰天&nbsp;&nbsp;&nbsp; 金牌数：14枚&nbsp;&nbsp;&nbsp; 金牌分布：自行车（1）、击剑（1）、举重（2）、柔道（2）、游泳（4）、跳水（1）、射击（2）、射箭（1）&nbsp;&nbsp;&nbsp; 看点综述：进入第二天，奥运会比赛项目全面铺开。金牌大户水上项目的比赛当天拉开序幕，游泳将决出4枚金牌。而中国队的强项跳水也将产生本届奥运会的第一枚金牌。男篮方面，姚明领军的中国队将遇上美国&#8220;梦八队&#8221;，这场比赛不得不看。&nbsp;&nbsp;&nbsp; 中国争金点：作为新科世锦赛冠军，王磊将在21时向中国男子击剑首枚奥运会金牌发起冲击。女子53公斤级举重中国队将派出李萍和邱红霞当中的一人参赛，男子56公斤级的比赛中国队的小将李争将顶替状态下滑的雅典奥运会亚军吴美锦。跳水比赛的首枚金牌将在女子3米板双人项目上产生，郭晶晶、吴敏霞将力保金牌不会旁落。此外，女子10米枪和女子柔道52公斤级比赛也值得关注。 </font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">8月11日　第叁天 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌数：13枚 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌分布：击剑（1）、举重（2）、柔道（2）、游泳（4）、跳水（1）、射击（2）、射箭（1） </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 看点综述：在经过第一个周末的小高潮之后，第三天比赛略趋于平静。皮划艇激流比赛将在这天开赛，虽然中国选手在这个项目中没有什么突出成绩，但从观赏性角度来说，激流回旋还是非常值得一看的，特别是在这样烈日炎炎的夏天。另外，集休闲、娱乐和竞技一身的沙滩排球也是不错的选择。 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 中国争金点：卫冕冠军和东道主的双重身份将让陈艳青在女子举重58公斤级的比赛中占据相当大的优势。小将林跃/火亮（或者周吕鑫）将参加跳水男子10米台双人的决赛，小将的组合能否在奥运会这种大赛上担起重任，有待关注。另外，射击场上男子10米气步枪决赛，雅典奥运会上的神奇小子朱启南将再次披挂上阵。 </font></p>
<p><font face="Verdana">8月12日　第肆天 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌数：19枚 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌分布：皮划艇（2）、击剑（1）、马术（2）、体操（1）、举重（2）、柔道（2）、摔跤（2）、游泳（4）、跳水（1）、射击（2） </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 看点综述：香港分赛场将迎来第一个决赛日，香港的体育迷有机会见证北京奥运会首枚马术金牌的产生。这一天将进行马术三项赛中的场地障碍赛决赛，集观赏性与竞技性于一身的赛事一定能让观众大饱眼福。全球观众喜爱的体操比赛也将在这天产生首枚金牌。 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 中国争金点：体操男团决赛肯定是当天中国队的重中之重，杨威领军的中国体操男队近年成绩不错，差的就是这块奥运会金牌。男子举重69公斤级，增加体重后的雅典奥运会62公斤级冠军石智勇将和这个项目的卫冕冠军张国政成为双保险。小将陈若琳、王鑫将参加跳水女子10米台双人项目的决赛。奥运会四朝元老谭宗亮将在男子50米枪慢射项目中为自己的首枚奥运金牌而奋力一搏。&nbsp;<br />
&nbsp;</font></p>
<p><font face="Verdana">8月13日　第伍天 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌总数：17枚 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌分布：自行车（2）、击剑（2）、体操（1）、举重（2）、柔道（2）、摔跤（2）、游泳（4）、跳水（1）、射击（1） </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 看点综述：这一天晚上全世界所有媒体都将会把镜头的焦点对准水立方的泳道，美国&#8220;超人&#8221;菲尔普斯正在为自己的奥运8金梦想而连续作战。在广泛受人关注的男足赛场上，中国队将在秦皇岛迎战巴西队，前世界足球先生小罗纳尔多的亮相势必会引爆全场球迷的热情。 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 中国争金点：上届世锦赛中国女子体操队首次站上了体操女子团体的最高峰，此番能否在奥运会上有所突破值得关注。水立方的泳道上，如果菲尔普斯因为连续作战体力出现问题，那么吴鹏完全可能凭借主场优势对他构成一定的挑战。女子举重69公斤级的刘春红，男子3米板双人的秦凯、王峰，女子25米运动枪的陈颖也都有机会在各自项目上为中国队赢得一枚金牌。 </font></p>
<p><font face="Verdana">8月14日　第陆天 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌总数：17枚 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌分布：皮划艇（2）、马术（1）、击剑（1）、体操（1）、柔道（2）、摔跤（3）、游泳（4）、射击（2）、射箭（1） </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 看点综述：美国男篮和卫冕冠军阿根廷男篮都会在这天出场，估计相对轻松的小组赛可以让观众看到表演性更强的篮球比赛。香港赛场上举行的马术盛装舞步比赛同样极具观赏性，马匹优雅的舞步与骑手精湛的驾驭技术都会给观众留下深刻的印象。<br />
中国争金点：在连续两届奥运会中与冠军失之交臂的全能王杨威将参加体操男子个人全能项目的争夺，这位28岁的老将连续两届世锦赛中都为中国队夺得了全能项目的金牌。在女子飞碟双多向比赛中，中国队的世界杯总决赛冠军魏宁将单枪匹马迎战众多国外高手的挑战。</font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">8月15日　第柒天 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌数：16枚 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌分布：田径（2）、羽毛球（1）、自行车（1）、击剑（1）、体操（1）、举重（2）、柔道（2）、游泳（4）、击剑（1）、射箭（1） </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 看点综述：产生金牌最多的田径比赛终于拉开了帷幕，这一天将进行男子铅球和女子万米的决赛，备受注目的男子百米大战也将进行前两轮的角逐。足球项目将进入淘汰赛阶段的比赛，女足4场1/4决赛将在各地举行。水上项目菲尔普斯将参加最擅长的200米个人混合泳决赛，继续为8枚金牌之梦奋斗。 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 中国争金点：羽毛球经过连日预赛后，今天将产生女双金牌，这也是中国羽球队把握最大的单项。齐晖将参加200米蛙泳的争夺，这是罗雪娟退役之后中国水军仅存不多的争金点。女子柔道78公斤以上级的比赛中25岁的佟文有望延续中国队在这个项目上的辉煌。 </font></p>
<p><font face="Verdana">　　8月16日　第捌天 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌总数：30枚 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌分布：田径（4）、赛艇（7）、羽毛球（2）、自行车（3）、击剑（1）、举重（1）、摔跤（2）、游泳（4）、网球（2）、射击（2）、帆船（2） </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 看点综述：北京奥运会第一波高潮来临，当天11个比赛项目将产生30枚金牌。青岛的奥林匹克帆船中心将诞生第一枚金牌。另一金牌大户赛艇将集中产生7枚金牌，这是除田径比赛之外单日单项产生金牌最多的一次。男子百米飞人大战决赛、网球女单决赛也会在当晚举行。博尔特或是莎娃，男性的速度或是女将的美艳，尽收眼底。 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 中国争金点：羽毛球项目将产生女子单打和男子双打两枚金牌，张宁和谢杏芳有望为中国队争夺这枚金牌。男子25米枪速射的争夺中，排名现世界第一的张鹏辉将会挑战三届奥运会冠军德国的舒曼。在当天举行的女子75公斤以上级的比赛中，卫冕冠军唐功红因伤无法出战，中国队如果获得这个项目的参赛资格，将会派出多哈亚运会冠军穆爽爽参与金牌争夺战。</font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">8月17日　第玖天 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌总数：34枚 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌分布：田径（6）、赛艇（7）、羽毛球（2）、自行车（1）、击剑（1）、体操（4）、举重（1）、摔跤（2）、游泳（4）、跳水（1）、网球（2）、乒乓球（1）、射击（1）、帆船（1） </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 看点综述：本届奥运会产生金牌最多的一天，34枚金牌分布在14个比赛项目中。游泳项目进行最后一天的比赛，体操项目将开始单项金牌的争夺，而国球乒乓球也将在这一天决出第一枚金牌。这一天赛场上的另一个重头戏——男子网球单打的决赛，瑞士天王费德勒在温布尔登铩羽而归之后已经誓言在北京夺回世界冠军的头衔。 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 中国争金点：羽毛球男单和混双竞争激烈，这两块金牌对中国队而言都需要去拼。程菲和肖钦将分别参加女子跳马和男子鞍马的比赛。2007年伦敦马拉松赛冠军周春秀将是本届奥运会女子马拉松金牌的有力争夺者。乒乓球项目的第一枚金牌来自女子团体，不出意外的话，张怡宁领军的中国队夺金把握应该还是相当大的。 </font></p>
<p><font face="Verdana">　　8月18日　第拾天 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌总数：18枚 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 金牌分布：田径（6）、自行车（2）、马术（1）、体操（3）、蹦床（1）、举重（1）、乒乓球（1）、铁人三项（1）、帆船（2） </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 看点综述：北京奥运会赛程过半，在连续两天产生30枚以上的金牌之后，这一天的金牌数也回落到18枚。但是中国观众的激情却不会因此而减退，因为飞人刘翔出场了！8月18日上午11时10分刘翔将在鸟巢迎来自己的北京奥运会&#8220;揭幕战&#8221;。以刘翔的实力进入第二轮当然不成问题，感受现场观众火爆的热情也是他的&#8220;必修课&#8221;之一。 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; 中国争金点：中国队这一天的争金点依然集中在几个优势项目上，体操的三个单项决赛分别是男子吊环、男子跳马和女子高低杠，而世锦赛亚军黄珊汕也可能为中国队夺得首枚女子蹦床金牌。乒乓球方面，面对拥有上届男单冠军柳承敏的韩国队，拥有王励勤、王皓、马琳的中国队必须在当晚的男团决赛中发挥出高水平。&nbsp;<br />
&nbsp;</font></p>
<p><font face="Verdana">&nbsp;</font></p>
<p><font face="Verdana">&nbsp;<br />
</font></p>
<img src ="http://www.cnblogs.com/qiubole/aggbug/1265618.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42130/" target="_blank">[新闻]Google十年市值达1500亿美元 创造奇迹</a>]]></description></item><item><title>北京奥运，中国预测夺金亮点</title><link>http://www.cnblogs.com/qiubole/archive/2008/08/12/1265611.html</link><dc:creator>伯乐共勉</dc:creator><author>伯乐共勉</author><pubDate>Tue, 12 Aug 2008 00:47:00 GMT</pubDate><guid>http://www.cnblogs.com/qiubole/archive/2008/08/12/1265611.html</guid><wfw:comment>http://www.cnblogs.com/qiubole/comments/1265611.html</wfw:comment><comments>http://www.cnblogs.com/qiubole/archive/2008/08/12/1265611.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/qiubole/comments/commentRss/1265611.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/qiubole/services/trackbacks/1265611.html</trackback:ping><description><![CDATA[<span class="bold">北京奥运，中国预测夺金亮点竟有七十之多！</span><br />
<br />
<div class="t_msgfont" id="message888415">五星级项目——<br />
共19个夺金点，不容有失<br />
乒乓球男团（王皓、马琳、王励勤）<br />
乒乓球女团（张怡宁、郭跃、王楠）<br />
乒乓球女单（张怡宁、郭跃、王楠）<br />
体操男团（杨威、李小鹏、黄旭、肖钦、陈一冰、邹凯）---------------------------------OK<br />
体操高低杠（何可欣、杨伊琳）<br />
体操吊环（陈一冰）<br />
体操双杠（杨威、李小鹏、黄旭）<br />
跳水男子10米台双人（<strong>林跃、火亮</strong>）--------------------------------------------------OK<br />
跳水女子3米板（<strong>郭晶晶、吴敏霞</strong>）----------------------------------------------------OK<br />
跳水女子双人3米板（<strong>郭晶晶、吴敏霞</strong>）------------------------------------------------OK<br />
羽毛球女双（杨维/张洁雯、杜婧/于洋、魏轶力/张亚雯）<br />
女子举重48公斤（杨炼、<strong>陈燮霞</strong>、王文娟）---------------------------------------------OK<br />
女子举重58公斤（<strong>陈艳青</strong>）-----------------------------------------------------------OK<br />
女子举重63公斤（刘海霞）<br />
女子举重69公斤（<strong>刘春红</strong>）------------------------------------------------------------OK<br />
男子举重69公斤（<strong>廖辉</strong>、石智勇、张国政）----------------------------------------------OK<br />
男子举重62公斤（杨帆、丘乐，<a class="font0037" href="http://2008.qq.com/athlete/8166/" target="_blank">张湘祥</a> ）<br />
柔道女子78公斤（杨秀丽）<br />
田径女子竞走（刘虹、姜静）</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="t_msgfont" id="message888416">四星级项目——<br />
23个夺金点，强势登场。<br />
体操女子团体（程菲、江钰源等）-----------------------------------------------------OK<br />
女子排球（冯坤、赵蕊蕊等）<br />
乒乓球男单（王皓、马琳、王励勤）<br />
跳水女子10米台（陈若琳、王鑫）----------------------------------------------------OK<br />
田径110米栏（刘翔）<br />
男子蹦床（叶帅、董栋）<br />
体操女子自由操（程菲）<br />
柔道女子52公斤级（冼东妹）--------------------------------------------------------OK<br />
赛艇女子双人双浆（李勤、田靓）<br />
体操男子全能（杨威、陈一冰）<br />
跳水女子10米双人（王鑫/陈若琳）---------------------------------------------------OK<br />
柔道女子78公斤以上（佟文）<br />
羽毛球女单（谢杏芳、张宁）<br />
女子10米气步枪（杜丽、赵颖慧）---------------------------------------------------Fail<br />
拳击48公斤级（邹市明）<br />
女子蹦床（黄珊汕）<br />
体操鞍马（肖钦）<br />
跳水男子3米板双人（王峰/秦凯）----------------------------------------------------OK<br />
跆拳道女子+67公斤（陈中）<br />
体操女子跳马（程菲）<br />
男子10米气步枪（朱启南、曹逸飞）-------------------------------------------------Fail<br />
皮划艇双人500米划艇（杨文军/孟关良）<br />
跆拳道女子48公斤级（吴静钰）</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="t_msgfont" id="message888417">三星项目——<br />
16夺金点，力求突破。<br />
羽毛球男单（林丹、鲍春来、陈金）<br />
羽毛球混双（郑波/高凌、谢中博/魏亚雯、何汉斌/于洋）<br />
网球女双（郑洁/晏紫）<br />
皮划艇激流回旋男子双人划艇（胡明海/舒俊榕）<br />
女子沙排（田佳/王洁、薛晨/张希）<br />
赛艇女子双人单浆无舵手（张亚歌/高玉兰）<br />
跳水男子3米板（秦凯、何冲）----------------------------------------------------OK<br />
女子曲棍球<br />
羽毛球男双（蔡赟/傅海峰、郭振东/谢中博）<br />
击剑女子佩剑个人（谭雪）--------------------------------------------------------Fail<br />
皮划艇女子单人皮艇（李彤、李晶晶）<br />
女子10米气步枪（任洁、郭文珺）--------------------------------------------------OK<br />
田径女子马拉松（周春秀、朱晓琳、魏亚楠）<br />
跳水男子10米台（周吕鑫、林跃）--------------------------------------------------OK<br />
女子飞碟双向（魏宁）</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="t_msgfont" id="message888418">二星级项目——<br />
12个夺金点，寻找黑马。<br />
男子25米枪速射（张鹏辉、刘忠生）<br />
自行车女子争先赛（郭爽）<br />
女子25米运动枪（陈颖、费逢吉）-------------------------------------------------OK<br />
击剑女子重剑个人（李娜、仲维萍）<br />
激光雷迪尔级帆船（徐莉佳）<br />
赛艇女子四人双浆（唐宾/奚爱华/金紫薇/冯桂鑫）<br />
射箭女子团体（张娟娟/郭丹/陈玲）<br />
女子米氏级帆板（殷剑）<br />
赛艇男子轻量级四人单浆（黄仲呜/吴崇魁/张林/田军）<br />
女子摔跤72公斤级（王旭、王娇、许晴）<br />
击剑女子佩剑团体（谭雪/包盈盈/赵媛媛/黄海洋）<br />
赛艇女子轻量级双人双浆（徐东香/严诗敏/陈海霞/谭美云）</div>
<img src ="http://www.cnblogs.com/qiubole/aggbug/1265611.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42130/" target="_blank">[新闻]Google十年市值达1500亿美元 创造奇迹</a>]]></description></item><item><title>实战 Firefox 扩展开发</title><link>http://www.cnblogs.com/qiubole/archive/2008/08/01/1258190.html</link><dc:creator>伯乐共勉</dc:creator><author>伯乐共勉</author><pubDate>Fri, 01 Aug 2008 06:53:00 GMT</pubDate><guid>http://www.cnblogs.com/qiubole/archive/2008/08/01/1258190.html</guid><wfw:comment>http://www.cnblogs.com/qiubole/comments/1258190.html</wfw:comment><comments>http://www.cnblogs.com/qiubole/archive/2008/08/01/1258190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/qiubole/comments/commentRss/1258190.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/qiubole/services/trackbacks/1258190.html</trackback:ping><description><![CDATA[<p>级别： 中级</p>
<p><a href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#author" cmimpressionsent="1">成 富</a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#104;&#101;&#110;&#103;&#102;&#98;&#106;&#64;&#99;&#110;&#46;&#105;&#98;&#109;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#23454;&#25112;&#32;&#70;&#105;&#114;&#101;&#102;&#111;&#120;&#32;&#25193;&#23637;&#24320;&#21457;" cmimpressionsent="1">mailto:chengfbj@cn.ibm.com?subject=实战 Firefox 扩展开发</a>), 软件工程师, IBM 中国软件开发中心<br />
</p>
<p>2008 年 2 月 28 日</p>
<blockquote>Firefox 浏览器自身提供良好的扩展结构，使得开发人员可以方便的扩展其行为。很多网站，比如 del.icio.us，都提供 Firefox 扩展来提供更好的用户体验。学习这方面的知识不仅对于网站开发人员是有用的，其他人也可以通过开发扩展来解决一些使用 Firefox 中遇到的具体问题。本文以一个能够批量下载某个 HTML 页面上所有图片的 Firefox 扩展作为案例，详细的介绍了 Firefox 扩展的开发流程。这其中包括构建开发环境，使用 XUL 来描述用户界面，使用 JavaScript 来为扩展增加行为，扩展的打包、发布和更新等方面的内容。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
<p><a name="N1005C"><span class="atitle">案例介绍</span></a></p>
<p>本文中所要构建的是一个能够批量下载某个 HTML 页面上所有图片的 Firefox 扩展。通常我们在浏览包含许多图片的网页时，如果想要把自己感兴趣的图片全部下载下来，需要逐一在图片上点击右键，然后选择另存为，再选择文件存放的目录，最后才能把图片保存在本机上。另外一种做法是把整个网页都保存下来，不过这样会保存不需要的信息，包括 JavaScript 脚本和 CSS 文件等，会增加所需的磁盘空间，浏览起来也不方便。该扩展要做的事情就是把网页上所有的图片在一个新窗口中列出来，用户可以勾选其感兴趣的图片，并指定需要保存的目录。然后该扩展能够一次性把用户选择的图片都下载下来。用户以后浏览起来也更加方便。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><a name="N10064"><span class="atitle">构建开发环境</span></a></p>
<p>在动手开发之前，首先需要构建扩展开发所需的环境。Firefox 把用户的个人信息，包括设置、已安装的扩展等，都保存在一个概要文件中，默认是使用名为 default 的概要文件。通过创建一个专门为开发使用的概要文件，可以不影响正常的使用，也不会破坏个人信息。为了创建另外一个概要文件，运行 <code>firefox &#8211;P</code>，在弹出的&#8220;选择概要文件&#8221;的对话框中，新建一个名为 dev 的概要文件，并使用此概要文件来运行 Firefox。接下来需要安装几个帮助开发的扩展，分别是 Venkman、Extension Developer's Extension 、Console<sup>2</sup> 、Chrome List 和 Firebug。可以在 <a href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#resources" cmimpressionsent="1">参考资源</a> 部分找到这些扩展的下载地址。最后修改 Firefox 的设置使得调试更加容易。在地址栏输入 <code>about:config</code> 可以打开 Firefox 的参数设置页面。按照如下的设置修改参数：</p>
<br />
<a name="N1007E"><strong>清单 1. Firefox 扩展开发环境参数设置</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            javascript.options.showInConsole = true //把 JavaScript 的出错信息显示在错误控制台
            nglayout.debug.disable_xul_cache = true //禁用 XUL 缓存，使得对窗口和对话框的修改不需要重新加载 XUL 文件
            browser.dom.window.dump.enabled  = true //允许使用 dump() 语句向标准控制台输出信息
            javascript.options.strict        = true //在错误控制台中启用严格的 JavaScript 警告信息
            </pre>
            </td>
        </tr>
    </table>
<br />
<p>至此，开发环境就构建完成了。当需要进行扩展开发时，运行 <code>firefox -P dev</code> 启动 Firefox 即可。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><a name="N1008B"><span class="atitle">构建初始的扩展目录结构</span></a></p>
<p>接下来正式进行扩展开发。首先介绍一下一个 Firefox 扩展的基本目录结构。</p>
<br />
<a name="fig-directory-layout"><strong>图 1. Firefox 扩展目录结构</strong></a><br />
<img height="193" alt="Firefox 扩展目录结构" src="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/firefox-extension-directory-layout.jpg" width="465" /> <br />
<p>在 图 1 中，content 目录下面存放的是扩展的描述界面的 XUL 文件和增加行为的 JavaScript 文件。locale 目录存放的是本地化相关的文件。如果需要支持英文和中文，就可以在 locale 目录下面新建 en-US 和 zh-CN 目录来存放相应的本地化字符串。skin 目录存放的是一些 CSS 文件，用来定义扩展的外观。chrome.manifest 是 Chrome 注册的清单文件（参见 <a href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#chrome-sidebar" cmimpressionsent="1">侧栏</a>）。install.rdf 分别包含了扩展安装的信息。</p>
<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
    <tr>
            <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
            <td>
            <table cellspacing="0" cellpadding="5" width="100%" border="1">
                <tr>
                        <td bgcolor="#eeeeee"><a name="chrome-sidebar"><strong>什么是 Chrome？</strong></a><br />
                        Chrome 指的是应用程序窗口的内容区域之外的用户界面元素的集合，这些用户界面元素包括工具条，菜单，进度条和窗口的标题栏等。Chrome 提供者能为特定的窗口类型（如浏览器窗口）提供 chrome。有三种基本的 chrome 提供者：
                        <ul>
                            <li>内容（Content）：通常是 XUL 文件。</li>
                            <li>区域（Locale） ：存放本地化信息。</li>
                            <li>皮肤（Skin）：描述 chrome 的外观。通常包含 CSS 和图像文件。 </li>
                        </ul>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<p>在构建了初始的目录结构之后，需要让 Firefox 能够识别并加载该扩展。首先需要找到当前的概要文件所对应的目录。在 Microsoft Windows 2000 和 XP 的电脑上面，该目录是 C:\Documents and Settings\&lt;您的登录用户名&gt;\Application Data\Mozilla\Firefox\Profiles。找到该目录之后，可以看到以 dev 结尾的目录，那就是我们之前构建的开发环境的概要文件所在的目录。在其下的 extensions 目录下面，新建一个文件，其文件名为 install.rdf 中指定的扩展的 ID，此处为 batchimagesdownloader@cn.ibm.com。该文件的内容就是扩展内容所在的实际目录，比如： C:\FirefoxExtDev\batchimagesdownloader。Firefox 就能识别并加载我们添加的扩展了。在每次对扩展做了一定的修改之后，不需要重新启动 Firefox，只需要安装之前介绍的 Extension Developer's Extension，并在 <strong>Tools</strong> 菜单中单击 <strong>Extension Developer</strong> &gt; <strong>Reload all Chrome</strong> 即可。接下来就可以尝试为扩展添加功能了。 </p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><a name="N100CA"><span class="atitle">构建基本的用户界面</span></a></p>
<p>我们首先从用户界面入手。如之前所述，我们希望在一个新的窗口中显示当前 HTML 页面中所有的图片，并可以让用户进行选择。Firefox 扩展使用 XUL 来描述其用户界面。XUL 提供了一套基于 XML 的描述方式，可以用来描述用户界面的各种组件，比如按钮、菜单和工具条等。最初始的界面包含显示图片的一个表格以及 OK 和 Cancel 两个按钮。</p>
<br />
<a name="code-basic-xul"><strong>清单 2. 基本用户界面的 XUL 描述</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            &lt;?xml version="1.0"?&gt;
            &lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?&gt;
            &lt;window
            id="batchimagesdownloader-mainwindow" title="Batch Images Downloader"
            orient="horizontal" onload="mainWindowOnLoad();"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
            &lt;vbox flex="1"&gt;
            &lt;vbox flex="1"&gt;
            &lt;label value="Images on this web page:" /&gt;
            &lt;spacer style="height: 5px"/&gt;
            &lt;hbox height="500" width="750" style="overflow:auto;"&gt;
            &lt;grid&gt;
            &lt;columns&gt;
            &lt;column/&gt;
            &lt;column/&gt;
            &lt;column/&gt;
            &lt;/columns&gt;
            &lt;rows id="imagesContainer"&gt;&lt;/rows&gt; &lt;!-- 显示图片的表格 --&gt;
            &lt;/grid&gt;
            &lt;/hbox&gt;
            &lt;/vbox&gt;
            &lt;spacer style="height: 10px"/&gt;
            &lt;hbox&gt;
            &lt;spacer flex="1"/&gt;
            &lt;button id="mainWindow-add-button" label="OK" default="true"
            oncommand="download();"/&gt;
            &lt;button id="mainWindow-cancel-button" label="Cancel" oncommand="close();"/&gt;
            &lt;/hbox&gt;
            &lt;spacer style="height: 5px"/&gt;
            &lt;/vbox&gt;
            &lt;/window&gt;</pre>
            </td>
        </tr>
    </table>
<br />
<p>上面就是显示图片的新窗口的界面元素的声明。下面需要添加用户的交互行为。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><a name="N100DE"><span class="atitle">添加菜单事件响应</span></a></p>
<p>我们希望当用户点击 Firefox 上面的一个菜单项时，弹出刚才构建的新窗口。我们这里要做的是向 Firefox 自带的 <strong>Tools</strong> 菜单添加一个新的名为 <strong>Batch Images Downloader</strong> 的菜单项。当用户点击此菜单项时，就会弹出 <a href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#code-basic-xul" cmimpressionsent="1">代码清单2</a>中定义的窗口。在扩展中可以使用覆盖（Overlay）来向已有的界面中添加元素。使用覆盖可以在运行时向一个 XUL 文档添加新的组件。我们在 chrome.manifest 中定义了名为 overlay.xul 的文件，会对 Firefox 已有的用户界面进行一定的修改。只需要在 overlay.xul 中添加下面的内容即可：</p>
<br />
<a name="N100F3"><strong>清单 3. 增加菜单项的 XUL 描述</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            &lt;menupopup id="menu_ToolsPopup"&gt;
            &lt;menuitem id="batchimagesdownloader-show" label="Batch Images Downloader"
            oncommand="BatchImagesDownloader.show(event);"/&gt;
            &lt;/menupopup&gt;</pre>
            </td>
        </tr>
    </table>
<br />
<p>上面定义了当点击菜单项时，会调用 <code>BatchImagesDownloader.show</code>方法，这是在 overlay.js 中定义的一个 JavaScript 方法，用来处理新窗口的弹出。overlay.js 由 overlay.xul 包含进来。</p>
<br />
<a name="N10103"><strong>清单 4. 菜单项的事件响应方法</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            var BatchImagesDownloader = {
            show : function() {
            var doc = window.getBrowser().selectedBrowser.contentDocument;
            var imageNodes = doc.getElementsByTagName("img"); //获取所有的 img 节点
            var params = {"imageNodes" : imageNodes};
            this.openWindow("BatchImagesDownloader.mainWindow",
            "chrome://batchimagesdownloader/content/mainWindow.xul",
            "chrome=yes,centerscreen", params);
            },
            //打开一个新的窗口，或是使得已经创建的窗口获得焦点
            openWindow : function(windowName, url, flags, params) {
            var windowsMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
            .getService(Components.interfaces.nsIWindowMediator);
            var aWindow = windowsMediator.getMostRecentWindow(windowName);
            if (aWindow) {
            aWindow.focus();
            }
            else {
            aWindow = window.openDialog(url, windowName, flags, params);
            }
            return aWindow;
            }
            };
            </pre>
            </td>
        </tr>
    </table>
<br />
<p>添加上述的代码之后，可以通过点击 <strong>Tools</strong> 菜单项下来的 <strong>Batch Images Downloader</strong> 菜单项来弹出新的窗口。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><a name="N10112"><span class="atitle">显示图片</span></a></p>
<p>可以在 <code>BatchImagesDownloader.show</code>方法中看到，当弹出新窗口的时候，会把当前页面上的所有 img 节点都作为参数传递给新打开的窗口。这些 img 节点就是需要展现给用户并供其选择的。接下来要做的就是在新窗口中显示这些图片。在 JavaScript 的方法中，可以像在 HTML 中的 DOM 操作一样，对 XUL 定义的 DOM 树进行修改。这其中包括使用 <code>document.createElementNS</code> 来创建新的 XUL 元素，同样也可以使用 CSS 来修改 XUL 元素的外观。</p>
<br />
<a name="N10125"><strong>清单 5. 显示图片的 JavaScript 方法</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            const COLUMNS_PER_ROW = 3;	//每行显示3张图片
            function mainWindowOnLoad() {
            var params = window.arguments[0];
            var imageNodes = params.imageNodes;
            displayImages(imageNodes);
            }
            function displayImages(imageNodes) {
            imageNodes = imageNodes || [];
            var cols = COLUMNS_PER_ROW, row, image, hbox, checkbox;
            var rows = document.getElementById("imagesContainer");
            for (var i = 0, n = imageNodes.length; i &lt; n; i++) {
            var imageNode = imageNodes[i];
            var imageSrc = imageNode.getAttribute("src");
            if (imageSrc == "") {
            continue;
            }
            if (cols &gt;= COLUMNS_PER_ROW) {
            row = document.createElementNS(XUL_NS, "row"); //开始新的一行
            row.setAttribute("align", "center");
            rows.appendChild(row);
            cols = 0;
            }
            else {
            hbox = document.createElementNS(XUL_NS, "hbox");
            hbox.setAttribute("style", "padding:5px 5px 5px 5px;");
            image = document.createElementNS(XUL_NS, "image");//创建 XUL 图像元素来显示图片
            image.setAttribute("src", imageSrc);
            checkbox = document.createElementNS(XUL_NS, "checkbox");//创建 XUL 复选框元素以供用户选择
            checkbox.setAttribute("imageUrl", imageSrc);
            hbox.appendChild(checkbox);
            hbox.appendChild(image);
            row.appendChild(hbox);
            cols++;
            }
            }
            }
            </pre>
            </td>
        </tr>
    </table>
<br />
<p>我们需要在新窗口加载完成之后，就显示当前页面的所有图片。因此需要注册新窗口的 onload 事件的响应方法。这里是 <code>mainWindowOnLoad</code>。在 <code>mainWindowOnLoad</code> 中，通过 <code>window.arguments[0]</code>可以获得作为打开新窗口的参数传进来的 img 节点列表。然后根据这些 img 节点的 src 属性，创建相应的 XUL 图像元素并显示在表格中，并在每个图片下面创建一个复选框以供用户选择。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><a name="N1013A"><span class="atitle">下载图片</span></a></p>
<p>为了让用户能够下载所选的图片，需要添加新的界面元素让用户可以指定下载图片存放的目录，并提供一个进度条来显示当前的下载进度。</p>
<br />
<a name="N10145"><strong>清单 6. 支持下载的用户界面 XUL 描述</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            &lt;hbox&gt;
            &lt;label value="Save images to" /&gt;
            &lt;textbox id="mainWindow-save-path" readonly="true" style="min-width: 15em;" flex="1"/&gt;
            &lt;button label="Browse..." oncommand="selectSaveDirectory();"/&gt;
            &lt;/hbox&gt;
            &lt;spacer style="height: 10px"/&gt;
            &lt;progressmeter mode="determined" id="downloadProgress"
            value="0" style="visibility:hidden;"/&gt;
            </pre>
            </td>
        </tr>
    </table>
<br />
<p>该扩展提供了一个默认的图片保存路径，那就是当前用户的根目录。用户也可以选择他想要的保存图片的目录。</p>
<br />
<a name="N10151"><strong>清单 7. 用户选择图片保存目录的 JavaScript 方法</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            var saveDirectory = getDefaultSaveDirectory();
            function selectSaveDirectory() {
            const nsIFilePicker = Components.interfaces.nsIFilePicker;
            var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
            fp.init(window, "", nsIFilePicker.modeGetFolder);
            var result = fp.show(); //显示目录选择对话框
            if (result == nsIFilePicker.returnOK) {
            var file = fp.file;
            saveDirectory = file;
            byId("mainWindow-save-path").value = file.path;//把目录的路径显示在文本框中
            }
            }
            //获得默认的图片保存目录，也就是当前用户的根目录
            function getDefaultSaveDirectory() {
            var file = Components.classes["@mozilla.org/file/directory_service;1"]
            .getService(Components.interfaces.nsIProperties)
            .get("Home", Components.interfaces.nsIFile);
            return file;
            }
            </pre>
            </td>
        </tr>
    </table>
<br />
<p>当用户对图片进行了选择，并点击 OK 之后，需要执行图片下载的任务。在下载图片中，会使用 Firefox 的 XPCOM 的实现，请参看 <a href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#xpcom-sidebar" cmimpressionsent="1">侧栏</a> 和 <a href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#resources" cmimpressionsent="1">参考资料</a>，获得关于 XPCOM 的更多信息。</p>
<br />
<a name="N10165"><strong>清单 8. 下载单张图片的 JavaScript 方法</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            function downloadSingleImage(uri, callback) {
            var ios = Components.classes["@mozilla.org/network/io-service;1"]
            .getService(Components.interfaces.nsIIOService);
            var imageURI = ios.newURI(uri, null, null); //创建图像的 URI
            var imageFileName = uri.substring(uri.lastIndexOf("/") + 1);
            var channel = ios.newChannelFromURI(imageURI);  //创建读取 URI 指定的数据流的通道
            var observer = {
            onStreamComplete : function(loader, context, status, length, result) {
            var file = Components.classes["@mozilla.org/file/local;1"]
            .createInstance(Components.interfaces.nsILocalFile);
            file.initWithFile(saveDirectory);  //图片保存的目录
            file.appendRelativePath(imageFileName);
            var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"]
            .createInstance(Components.interfaces.nsIFileOutputStream);
            stream.init(file, -1, -1, 0);
            var bstream = Components.classes["@mozilla.org/binaryoutputstream;1"]
            .createInstance(Components.interfaces.nsIBinaryOutputStream);
            bstream.setOutputStream(stream);
            bstream.writeByteArray(result, length); //把图片流的全部字节写入输出文件流中
            if (stream instanceof Components.interfaces.nsISafeOutputStream) {
            stream.finish();
            }
            else {
            stream.close();
            }
            if (typeof callback == "function") {
            callback();
            }
            }
            };
            var streamLoader = Components.classes["@mozilla.org/network/stream-loader;1"]
            .createInstance(Components.interfaces.nsIStreamLoader);
            streamLoader.init(channel, observer, null);
            }
            </pre>
            </td>
        </tr>
    </table>
<br />
<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
    <tr>
            <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
            <td>
            <table cellspacing="0" cellpadding="5" width="100%" border="1">
                <tr>
                        <td bgcolor="#eeeeee"><a name="xpcom-sidebar"><strong>什么是 XPCOM？</strong></a><br />
                        XPCOM 是一种跨平台的组件对象模型，类似于微软的 COM。它有多种的语言绑定，可以在 JavaScript，Java，Python 和 C++ 中使用和实现 XPCOM 的组件。XPCOM 本身提供了一系列核心组件和类，比如文件和内存管理，线程，基本的数据结构（字符串，数组）等。</td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<p>这里的实现方式是读取从远程获取的图片数据流，并把相应的数据写入到本地磁盘指定的目录中。为了实现以异步的方式读取和保存数据，使用了 <code>nsIStreamLoader</code> 接口的实现。它从指定的通道读取数据，当数据读取完成之后，会通知相应的监听器。在这里，我们用图片的URL地址来初始化一个通道，同时创建了一个监听器。在 <code>onStreamComplete</code> 的方法中，把得到的图片字节流写入到本地文件存储中。最后，如果注册了回调函数，就执行此回调函数。</p>
<br />
<a name="N10182"><strong>清单 9. 下载用户选择的全部图片的 JavaScript 方法</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td class="code-outline">
            <pre class="displaycode">
            function download() {
            var rows = document.getElementById("imagesContainer");
            var checkboxes = rows.getElementsByTagName("checkbox");
            var imageUrls = [];
            for (var i = 0, n = checkboxes.length; i &lt; n; i++) {
            if (checkboxes[i].checked) {
            imageUrls.push(checkboxes[i].getAttribute("imageUrl")); //用户选择的图片的 URL
            }
            }
            var progressmeter = byId("downloadProgress");
            progressmeter.style.visibility = "visible";
            var total = imageUrls.length, step = 100 / total, current = 0;
            for (var i = 0; i &lt; total; i++) {
            downloadSingleImage(imageUrls[i], function() {
            var value = parseInt(progressmeter.value); //更新进度条
            progressmeter.value = value + step;
            });
            }
            close();
            }
            </pre>
            </td>
        </tr>
    </table>
<br />
<p>下载全部图片时，会逐个检查复选框的状态，把用户选择的图片的 URL 记录下来。对每张图片，都会调用 <code>downloadSingleImage</code> 以异步的方式来下载。在单张图片下载完成之后，会有回调函数来通知主窗口，更新进度条的状态。当所有图片都下载完成之后，关闭当前窗口。</p>
<p>至此，整个扩展就开发完成了。实际的扩展的截图如下：</p>
<br />
<a name="fig-screenshot"><strong>图 2. 该 Firefox 扩展实际使用的截图</strong></a><br />
<img height="754" alt="该 Firefox 扩展实际使用的截图" src="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/batch-image-downloader-screenshot-small.jpg" width="572" /> <br />
<p>在 图 2 中，HTML 页面的内容是使用&#8220;flower&#8221;作为关键字来访问百度图片搜索。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><a name="N101A4"><span class="atitle">打包、发布和更新</span></a></p>
<p><a name="N101AA"><span class="smalltitle">打包</span></a></p>
<p>扩展打包的过程非常简单。只需要把整个目录的内容打包成一个 ZIP 格式的文件，并把文件的扩展名改为 xpi 即可。需要注意的是 install.rdf 要在 ZIP 文件的根目录下面，这样扩展才能安装到 Firefox 中。 </p>
<p><a name="N101B3"><span class="smalltitle">发布</span></a></p>
<p>如果您想让别人也来使用您开发的扩展，一种方式是直接把打包好的 xpi 文件发给对方，他只需要用 Firefox 打开这个文件，就会自动提示安装。另外一种方式是把该 xpi 文件存放在某个公开的 HTTP 服务器中，对方只需要用 Firefox 访问该 xpi 文件，就同样会自动提示安装。这里需要注意的是要正确的设置 xpi 文件的 MIME 类型。Firefox 能识别的 xpi 文件的 MIME 类型是 application/x-xpinstall。您可能需要配置您的 HTTP 服务器。</p>
<p><a name="N101BC"><span class="smalltitle">更新</span></a></p>
<p>如果您的扩展的开发周期较长，需要发布多个版本的话，可以利用扩展的自动更新的能力。这样当有新的版本发布时，Firefox 会自动提示用户去获取最新的版本。要实现自动更新，需要在扩展的 install.rdf 中指定描述更新信息的 rdf 文件的位置，该 rdf 文件通常命名为 update.rdf。在 update.rdf 中声明了当前最新的版本号和最新版本的下载地址。如果用户安装的扩展的版本低于 update.rdf 中声明的版本，则 Firefox 会提示用户是否更新。请参考本文附带的 <a href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#downloads" cmimpressionsent="1">源代码</a> 中的 update.rdf 文件。 </p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><a name="N101C9"><span class="atitle">声明</span></a></p>
<p>本文章仅代表作者本人观点，与 IBM 公司无关。 </p>
<br />
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            <table cellspacing="0" cellpadding="0" border="0">
                <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/index.html#main" cmimpressionsent="1"><strong>回页首</strong></a></td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
<br />
<br />
<p><span class="atitle"><a name="download">下载</a></span></p>
<table class="data-table-1" cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
            <th scope="col">描述</th>
            <th scope="col">名字</th>
            <th scope="col">大小</th>
            <th scope="col">下载方法</th>
        </tr>
        <tr>
            <th class="tb-row" scope="row">批量下载图片的 Firefox 扩展的源代码</th>
            <td noWrap>batchimagesdownloader.zip</td>
            <td noWrap>4KB</td>
            <td noWrap><a class="fbox" href="http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/batchimagesdownloader.zip" cmimpressionsent="1"><strong>HTTP</strong></a></td>
        </tr>
    </table>
<table cellspacing="0" cellpadding="0" border="0">
    <tr valign="top">
            <td colspan="5"><img height="12" alt="" src="http://www.ibm.com/i/c.gif" width="12" border="0" /></td>
        </tr>
        <tr>
            <td><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" width="16" /></td>
            <td><a class="fbox" href="http://www.ibm.com/developerworks/cn/whichmethod.html" cmimpressionsent="1">关于下载方法的信息</a></td>
            <td><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="50" /></td>
        </tr>
    </table>
<br />
<br />
<p><a name="resources"><span class="atitle">参考资料 </span></a></p>
<strong>学习</strong><br />
<ul>
    <li>在 <a href="http://developer.mozilla.org/en/docs/Extensions" cmimpressionsent="1">Mozilla 开发者中心的扩展开发专题</a> 中学习更多关于扩展开发的知识。 <br />
    <br />
    </li>
    <li>在 <a href="http://developer.mozilla.org/en/docs/XPCOM" cmimpressionsent="1">Mozilla 开发者中心的 XPCOM 专题</a> 中学习更多关于 XPCOM 的知识。 <br />
    <br />
    </li>
    <li>在 <a href="http://xulplanet.com/" cmimpressionsent="1">XUL Planet</a> 中学习更多关于 XUL 的知识。 <br />
    <br />
    </li>
    <li>阅读&#8220;<a href="http://www.ibm.com/developerworks/cn/xml/x-xul/" cmimpressionsent="1">XUL － 快速开发跨平台易用用户接口的新途径</a>&#8221;：介绍 XML User-interface Language - 基于 XML 的用户接口语言。 <br />
    <br />
    </li>
    <li>阅读&#8220;<a href="http://www.ibm.com/developerworks/cn/edu/x-dw-x-xulintro.html" cmimpressionsent="1">XML 用户界面语言（XUL）开发入门</a>&#8221;：在这个教程中，您将使用 XUL 进行编程。 <br />
    <br />
    </li>
    <li>阅读&#8220;<a href="http://www.ibm.com/developerworks/cn/web/wa-xul1/" cmimpressionsent="1">使用 XUL 实现浏览器扩展，第 1 部分: 使用用户界面特性创建一个 Firefox 浏览器扩展</a>&#8221;：介绍如何创建超越 Web 浏览器内置功能的扩展。 <br />
    <br />
    </li>
    <li>阅读&#8220;<a href="http://www.ibm.com/developerworks/cn/web/wa-xul2/" cmimpressionsent="1">使用 XUL 实现浏览器扩展，第 2 部分: 组建一个跨平台的 Firefox 扩展</a>&#8221;：了解如何构建功能强大的灵活的 Mozilla 浏览器扩展。 <br />
    <br />
    </li>
    <li>阅读&#8220;<a href="http://www.ibm.com/developerworks/cn/edu/x-dw-x-ajaxxul.html" cmimpressionsent="1">创建动态的 Firefox 用户界面</a>&#8221;：学习如何使用 Ajax 从 Web 服务器下载 XML 数据，以及如何使用 XSLT 将 XML 数据动态地转换为用 XUL 表达的 Firefox 用户界面元素。 <br />
    <br />
    </li>
    <li>通过 developerWorks <a href="http://www.ibm.com/developerworks/cn/web/" cmimpressionsent="1">Web 开发专区</a> 中介绍 Web 技术的文章和教程扩展您的网站开发技巧。 <br />
    <br />
    </li>
</ul>
<br />
<strong>获得产品和技术</strong><br />
<ul>
    <li>下载扩展开发者常用的扩展
    <ul>
        <li><a href="https://addons.mozilla.org/en-US/firefox/addon/216" cmimpressionsent="1">Venkman</a></li>
        <li><a href="http://ted.mielczarek.org/code/mozilla/extensiondev/" cmimpressionsent="1">Extension Developer's Extension</a></li>
        <li><a href="https://addons.mozilla.org/en-US/firefox/addon/1815" cmimpressionsent="1">Console<sup>2</sup> </a></li>
        <li><a href="https://addons.mozilla.org/firefox/4453" cmimpressionsent="1">Chrome List</a></li>
        <li><a href="https://addons.mozilla.org/en-US/firefox/addon/1843" cmimpressionsent="1">Firebug</a> </li>
    </ul>
    <br />
    </li>
</ul>
<br />
<strong>讨论</strong><br />
<ul>
    <li><a href="http://www.cnblogs.com/qiubole/admin/news://news.mozilla.org/mozilla.dev.extensions" cmimpressionsent="1">Mozilla 扩展开发的新闻组</a> <br />
    <br />
    </li>
    <li><a href="http://groups.google.com/group/mozilla.dev.extensions" cmimpressionsent="1">Mozilla 扩展开发的 Google 讨论组</a> <br />
    <br />
    </li>
</ul>
<img src ="http://www.cnblogs.com/qiubole/aggbug/1258190.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42129/" target="_blank">[新闻]GMail:回过头来支持IE6</a>]]></description></item><item><title>了解数字证书</title><link>http://www.cnblogs.com/qiubole/archive/2008/06/03/1212990.html</link><dc:creator>伯乐共勉</dc:creator><author>伯乐共勉</author><pubDate>Tue, 03 Jun 2008 10:11:00 GMT</pubDate><guid>http://www.cnblogs.com/qiubole/archive/2008/06/03/1212990.html</guid><wfw:comment>http://www.cnblogs.com/qiubole/comments/1212990.html</wfw:comment><comments>http://www.cnblogs.com/qiubole/archive/2008/06/03/1212990.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/qiubole/comments/commentRss/1212990.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/qiubole/services/trackbacks/1212990.html</trackback:ping><description><![CDATA[<p>虽然公钥加密通过允许许多人使用一个密钥来简化了密钥管理，但存在一个问题：如何分发公钥，以便用户可以找到它并知道它是有效的。</p>
<p>在 S/MIME 中，此问题的解决方案是使用数字证书。数字证书是 S/MIME 与其他许多竞争的邮件安全解决方案的不同之处。</p>
<div class="MTPS_CollapsibleRegion" id="ctl00_rs1_mainContentContainer_cpe89348">
<div class="CollapseRegionLink" id="ctl00_rs1_mainContentContainer_cpe89348_h"><img id="ctl00_rs1_mainContentContainer_cpe89348_i" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-right-width: 0px" src="http://i.technet.microsoft.com/Platform/Controls/CollapsibleArea/resources/minus.gif"  alt="" />&nbsp;了解数字证书与公钥加密 </div>
<div class="MTPS_CollapsibleSection" id="ctl00_rs1_mainContentContainer_cpe89348_c" style="display: block; overflow: visible; width: auto; height: auto">
<div class="MTPS_CollapsibleSection" id="" style="border-right: medium none; border-top: medium none; display: block; border-left: medium none; border-bottom: medium none"><a name="sectionToggle0"><!----></a>
<p>数字证书是数字形式的标识，与护照或驾驶员执照十分类似。数字证书是数字凭据，它提供有关实体标识的信息以及其他支持信息。数字证书是由称为证书颁发机构 (CA) 的权威机构颁发的。由于数字证书由证书权威机构颁发，因此由该权威机构担保证书信息的有效性。此外，数字证书只在特定的时间段内有效。</p>
<p>数字证书对公钥加密提供支持，因为数字证书包含证书中所标识的实体的公钥。由于证书将公钥与特定的个人匹配，并且该证书的真实性由颁发机构保证，因此，数字证书为如何找到用户的公钥并知道它是否有效这一问题提供了解决方案。这些问题通过用户从数字证书中获取另一用户的公钥来解决。该用户知道它是有效的，因为该证书是由可信任的证书颁发机构颁发的。 </p>
<p>此外，数字证书依赖公钥加密来证明证书自己的身份。当颁发数字证书时，证书颁发机构使用它自己的私钥对证书进行签名。若要验证数字证书的真实性，用户可以获取该证书颁发机构的公钥，并对证书使用该公钥，以确定它是否是由该证书颁发机构签名的。</p>
<h3 class="subHeading">了解数字证书的结构</h3>
<div class="subSection">
<p>要使数字证书有用，它的结构必须采用一种可理解且可靠的形式，以便人们可以轻松地检索并理解证书内的信息。例如，护照采用这样一种结构：人们可以轻松地理解以前从未见过的那一类护照中的信息。同样，只要数字证书是标准化的，则无论颁发该证书的是哪个机构，人们都可以阅读并理解该证书。</p>
<p>S/MIME 标准规定：用于 S/MIME 的数字证书应遵守国际电信同盟 (ITU) X.509 标准。S/MIME 版本 3 明确要求数字证书应遵循 X.509 的第 3 版。由于 S/MIME 依赖于已建立的数字证书结构公认标准，因此 S/MIME 标准建立在该标准的发展之上，从而提高了它的认可度。</p>
<p>X.509 标准规定数字证书应包含标准化信息。具体地说，X.509 版本 3 证书包含下列字段： </p>
<ul>
    <li><strong>版本号</strong> 证书所遵循的 X.509 标准的版本。<br />
    <li><strong>序列号</strong> 唯一标识证书且由证书颁发机构颁发的编号。<br />
    <li><strong>证书算法标识</strong> 证书颁发机构用来对数字证书进行签名的特定公钥算法的名称。<br />
    <li><strong>颁发者名称</strong> 实际颁发该证书的证书颁发机构的标识。<br />
    <li><strong>有效期</strong> 数字证书保持有效的时间段，并包含起始日期和过期日期。<br />
    <li><strong>使用者名称</strong> 数字证书所有者的姓名。<br />
    <li><strong>使用者公钥信息</strong> 与数字证书所有者关联的公钥以及与该公钥关联的特定公钥算法。<br />
    <li><strong>颁发者唯一标识符</strong> 可以用来唯一标识数字证书颁发者的信息。<br />
    <li><strong>使用者唯一标识符</strong> 可以用来唯一标识数字证书所有者的信息。<br />
    <li><strong>扩充信息</strong> 与证书的使用和处理有关的其他信息。<br />
    <li><strong>证书颁发机构的数字签名</strong> 使用证书算法标识符字段中指定的算法以及证书颁发机构的私钥进行的实际数字签名。<br />
    </li>
</ul>
<p>由于 S/MIME 需要 X.509 v3 证书，因此该信息还描述了 S/MIME 对其特定证书所使用的特征。</p>
<div class="alert">
<table width="100%">
    <tbody>
        <tr>
            <th align="left"><img class="note" src="http://technet.microsoft.com/zh-cn/library/Bb123848.note(zh-cn,EXCHG.65).gif"  alt="" />重要信息：</th>
        </tr>
        <tr>
            <td>X.509 v3 标准是统管数字证书的标准。它没有为特定于 S/MIME 的证书提供标准。有关特定于 S/MIME 的数字证书的信息在 S/MIME RFC 中说明。 </td>
        </tr>
    </tbody>
</table>
</div>
<p>虽然数字证书是电子的，但请记住，由于数字证书是标准化的，因此可以用在大量设备上，而不仅仅是个人计算机上。数字证书可以用在手持设备、手机和便携式卡（称为智能卡）上。智能卡可以用在各种不同的设备上，并且在某些方面，很适合用于数字证书。智能卡使得数字证书可以像传统的驾驶员执照或护照一样便于携带，便于使用。 </p>
<p>对于 S/MIME 的成功，通过 S/MIME RFC 和 X.509 版本 3 标准实现的 S/MIME 证书标准化是一个关键要素，因为它使得任何遵守该标准的应用程序都能理解数字证书。</p>
</div>
<h3 class="subHeading">数字证书和公钥基础结构</h3>
<div class="subSection">
<p>公钥加密的优势之一是，由于用一个密钥对取代了大量的对称密钥，因此减少了密钥管理的工作量。数字证书进一步增强了这一优势，它解决了公钥的分发和管理问题。但是，数字证书无法进行自我管理。由于数字证书固有的广为分发的特点，因此，设计这些证书的管理方案时，必须考虑到数字证书的分发性这一特点。数字证书需要一种有效的基础结构，以便在证书的使用环境中管理证书。公钥基础结构 (PKI) 与数字证书是不可分割的。PKI 负责颁发证书，它通过目录确保这些证书的分发，并验证证书。PKI 负责基础工作，其中包括支持数字证书，并使它们可以提供 S/MIME 等服务所依赖的功能。 </p>
<p>由于 PKI 的规模大，而且很复杂，因此超过了本书所讲述的范围。这里所提供的信息着重讲述 PKI 和数字签名如何配合工作，以实现邮件安全性。有许多很优秀的资源讲述了 PKI。您可以从 PKI 供应商的文档以及其他专门涉及 PKI 的信息源中获取有关 PKI 的详细信息。</p>
</div>
</div>
</div>
</div>
<div class="MTPS_CollapsibleRegion" id="ctl00_rs1_mainContentContainer_cpe89349">
<div class="CollapseRegionLink" id="ctl00_rs1_mainContentContainer_cpe89349_h"><img id="ctl00_rs1_mainContentContainer_cpe89349_i" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-right-width: 0px" src="http://i.technet.microsoft.com/Platform/Controls/CollapsibleArea/resources/minus.gif"  alt="" />&nbsp;PKI 如何实现邮件安全性 </div>
<div class="MTPS_CollapsibleSection" id="ctl00_rs1_mainContentContainer_cpe89349_c" style="display: block; overflow: visible; width: auto; height: auto">
<div class="MTPS_CollapsibleSection" id="" style="border-right: medium none; border-top: medium none; display: block; border-left: medium none; border-bottom: medium none"><a name="sectionToggle1"><!----></a>
<p>PKI 通过颁发证书，并使证书可以通过目录进行访问，来提供使数字证书得以使用的方式。PKI 还通过验证证书的真实性、证书的有效性并因此而验证证书的可信性来验证数字证书。这些服务对于数字证书非常关键，因为数字证书使用第三方证书颁发机构，从而依赖于分布式模型。 </p>
<p>颁发数字证书并将其发布到目录中的特定方式取决于特定的 PKI 产品及其实现方法。通常，PKI 会颁发数字证书，并将有关这些证书的信息发布到目录中，以便其他应用程序可以从目录中访问该信息。其中的部分信息用于验证数字证书。如<a id="ctl00_rs1_mainContentContainer_ctl06" onclick="javascript:Track('ctl00_rs1_mainContentContainer_cpe89349_c|ctl00_rs1_mainContentContainer_ctl06',this);" href="http://technet.microsoft.com/zh-cn/library/aa998077(EXCHG.65).aspx">了解公钥加密</a>中的&#8220;使用公钥加密实现邮件的安全性&#8221;中所讨论，邮件安全操作需要访问发件人和收件人双方的公钥。由于数字证书提供此信息，因此访问用户的数字证书对于邮件安全系统而言至关重要。通过提供数字证书的可访问性，PKI 利用了公钥加密在简化密钥管理（无需手动交换密钥）方面所具有的优势。PKI 通过目录来使数字证书可用，以便应用程序可以在需要时检索数字证书。</p>
<p>若要了解 PKI 如何验证证书，请记住证书颁发机构在颁发数字证书方面的角色。如本主题前面的&#8220;了解数字证书与公钥加密&#8221;中所讨论，证书颁发机构担保标识的有效性，并通过使用其公钥对数字证书进行签名来说明这一点。检查证书的真实性意味着必须验证证书颁发机构的数字签名。PKI 通过为验证证书颁发机构的签名提供手段来验证证书。如果无法验证签名，则可以将证书视为不可信。 </p>
<p>如本主题开头所述，任何安全方法都不是十全十美的。数字证书的安全性可能被破坏，这通常发生在私钥丢失的情况下。要使数字证书可信，必须存在一种在数字证书过期前将其取消或&#8220;吊销&#8221;的方法，就好像可以取消被盗的信用卡。证书吊销是 PKI 用来支持数字证书的另一关键服务，也是数字证书验证过程的另一部分。</p>
<p>由于 PKI 确保数字证书可信，因此 PKI 是数字证书不可或缺的一个部分。如果没有 PKI，您将无法使用数字证书。由于 Exchange Server 2003 支持 X.509 v3 证书，因此具体哪些 PKI 支持 Exchange 安装将取决于 Exchange 所使用的数字证书。但是，从邮件安全性的角度来看，所有 PKI 都提供这些基础服务以支持数字证书。具体的 PKI 之间的差异与实现和设计有关，并与每一个 PKI 部署的具体情况有关。</p>
</div>
</div>
</div>
<div class="MTPS_CollapsibleRegion" id="ctl00_rs1_mainContentContainer_cpe89350">
<div class="CollapseRegionLink" id="ctl00_rs1_mainContentContainer_cpe89350_h"><img id="ctl00_rs1_mainContentContainer_cpe89350_i" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-right-width: 0px" src="http://i.technet.microsoft.com/Platform/Controls/CollapsibleArea/resources/minus.gif"  alt="" />&nbsp;使用数字证书实现邮件安全性 </div>
<div class="MTPS_CollapsibleSection" id="ctl00_rs1_mainContentContainer_cpe89350_c" style="display: block; overflow: visible; width: auto; height: auto">
<div class="MTPS_CollapsibleSection" id="" style="border-right: medium none; border-top: medium none; display: block; border-left: medium none; border-bottom: medium none"><a name="sectionToggle2"><!----></a>
<p>了解数字证书以及它如何支持公钥加密后，下一步便是将该信息应用于邮件安全领域。下一部分向您介绍数字证书如何为核心安全服务（包括数字签名和邮件加密）提供支持。</p>
<h3 class="subHeading">如何将数字证书用于数字签名</h3>
<div class="subSection">
<p>如<a id="ctl00_rs1_mainContentContainer_ctl11" onclick="javascript:Track('ctl00_rs1_mainContentContainer_cpe89350_c|ctl00_rs1_mainContentContainer_ctl11',this);" href="http://technet.microsoft.com/zh-cn/library/aa998077(EXCHG.65).aspx">了解公钥加密</a>中的&#8220;公钥加密和数字签名&#8221;中所讨论，公钥与用户私钥的关系使得收件人可以识别并验证发件人的邮件。数字证书通过提供可靠的公钥分发和访问方式来提供对公钥加密的支持。发件人对邮件进行签名时，将提供与数字证书上可用的公钥关联的私钥。反过来，当收件人验证邮件上的数字签名时，将从发件人的数字证书中获取公钥以执行验证。下图显示在添加了数字证书的支持元素的情况下进行签名的顺序。 </p>
<div><strong>
<p>
<p>数字证书以及电子邮件的数字签名</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Bb123848.35451fb8-5e11-4d67-ba6e-e5d4da6febca(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>捕获邮件。<br />
    <li>计算邮件的哈希值。<br />
    <li>从发件人的数字证书中检索发件人的私钥。<br />
    <li>使用发件人的私钥加密哈希值。<br />
    <li>将加密的哈希值作为数字签名附加到邮件中。<br />
    <li>发送邮件。<br />
    </li>
</ol>
<p>下图显示在添加了数字证书的支持元素的情况下进行验证的顺序。 </p>
<div><strong>
<p>
<p>数字证书以及验证电子邮件的数字签名</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Bb123848.d1b14a27-5cfb-4df2-89f7-990219378716(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>接收邮件。<br />
    <li>从邮件中检索包含加密哈希值的数字签名。<br />
    <li>检索邮件。<br />
    <li>计算邮件的哈希值。<br />
    <li>从发件人的数字证书中检索发件人的公钥。<br />
    <li>使用发件人的公钥解密加密的哈希值。<br />
    <li>将解密的哈希值与接收邮件时产生的哈希值进行比较。<br />
    <li>如果值匹配，则说明邮件有效。<br />
    </li>
</ol>
<p>这一系列操作显示，数字证书可以为验证数字签名而让验证过程访问公钥。</p>
</div>
<h3 class="subHeading">如何将数字证书用于邮件加密</h3>
<div class="subSection">
<p>就像数字证书通过使公钥可用于验证过程来支持数字签名一样，数字证书还通过使公钥可用于加密过程来支持邮件加密。如<a id="ctl00_rs1_mainContentContainer_ctl12" onclick="javascript:Track('ctl00_rs1_mainContentContainer_cpe89350_c|ctl00_rs1_mainContentContainer_ctl12',this);" href="http://technet.microsoft.com/zh-cn/library/aa998077(EXCHG.65).aspx">了解公钥加密</a>中的&#8220;公钥加密和邮件加密&#8221;中所讨论，发件人可以访问收件人的公钥，这使得发件人可以加密邮件，从而确保只有收件人能够解密该邮件。这一次，使加密成为可能的是收件人的数字证书。与数字签名一样，数字证书中的公钥使得此操作成为可能。下图显示在具有数字证书的支持元素的情况下进行加密的顺序。 </p>
<div><strong>
<p>
<p>数字证书以及电子邮件的加密</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Bb123848.21058391-2d70-42f9-bf25-8ead79705b27(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>捕获邮件。<br />
    <li>从收件人的数字证书中检索公钥。<br />
    <li>生成一次性对称会话密钥。<br />
    <li>使用会话密钥对邮件执行加密操作。<br />
    <li>使用收件人的公钥加密会话密钥。<br />
    <li>将加密的会话密钥包含在加密的邮件中。<br />
    <li>发送邮件。<br />
    </li>
</ol>
<p>下图显示在添加了数字证书的支持元素的情况下进行解密的顺序。 </p>
<div><strong>
<p>
<p>数字证书以及电子邮件的解密</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Bb123848.50f0afca-e520-46b5-8e12-6e295dfe86d9(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>接收邮件。<br />
    <li>从邮件中检索加密的邮件和加密的会话密钥。<br />
    <li>从收件人的数字证书中检索收件人的私钥。<br />
    <li>使用收件人数字证书中的收件人私钥解密会话密钥。<br />
    <li>使用解密的会话密钥解密邮件。<br />
    <li>将未加密的邮件返回给收件人。<br />
    </li>
</ol>
</div>
<h3 class="subHeading">如何将数字证书用于数字签名和邮件加密</h3>
<div class="subSection">
<p>数字签名和邮件加密互为补充。下图显示在添加了数字签名的支持元素的情况下进行签名和加密的顺序。 </p>
<div><strong>
<p>
<p>数字证书以及对电子邮件进行数字签名和加密</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Bb123848.e81cca9b-c780-49d9-a3f9-69cc3c442183(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>捕获邮件。<br />
    <li>计算邮件的哈希值。<br />
    <li>从发件人的数字证书中检索发件人的私钥。<br />
    <li>从收件人的数字证书中检索收件人的公钥。<br />
    <li>使用发件人的私钥加密哈希值。<br />
    <li>将加密的哈希值作为数字签名附加到邮件中。<br />
    <li>生成一次性对称会话密钥。<br />
    <li>使用会话密钥对邮件执行加密操作。<br />
    <li>使用收件人的公钥加密会话密钥。<br />
    <li>将加密的会话密钥包含在加密的邮件中。<br />
    <li>发送邮件。<br />
    </li>
</ol>
<p>下图显示在添加了公钥加密的支持元素的情况下对数字签名进行解密和验证的顺序。 </p>
<div><strong>
<p>
<p>数字证书以及解密电子邮件和验证数字签名</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Bb123848.97705e57-0a94-4197-99c3-40bb58a9eaa0(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>接收邮件。<br />
    <li>从邮件中检索加密的邮件和加密的会话密钥。<br />
    <li>从收件人的数字证书中检索收件人的私钥。<br />
    <li>使用收件人数字证书中的收件人私钥解密会话密钥。<br />
    <li>使用解密的会话密钥解密邮件。<br />
    <li>从邮件中检索包含加密哈希值的数字签名。<br />
    <li>计算邮件的哈希值。<br />
    <li>从发件人的数字证书中检索发件人的公钥。<br />
    <li>使用发件人的公钥解密加密的哈希值。<br />
    <li>将解密的哈希值与接收邮件时产生的哈希值进行比较。<br />
    <li>如果值匹配，则说明邮件有效。<br />
    <li>将未加密的邮件返回给收件人。<br />
    </li>
</ol>
<p>通过了解数字证书如何实现公钥加密，以及公钥加密如何为数字签名和邮件加密提供基本的安全服务，您已了解 S/MIME 邮件安全的工作原理。这些概念共同组成了邮件安全的基础核心。</p>
</div>
</div>
</div>
</div>
<img src ="http://www.cnblogs.com/qiubole/aggbug/1212990.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42128/" target="_blank">[新闻]Google十年大变样</a>]]></description></item><item><title>了解公钥加密</title><link>http://www.cnblogs.com/qiubole/archive/2008/06/03/1212941.html</link><dc:creator>伯乐共勉</dc:creator><author>伯乐共勉</author><pubDate>Tue, 03 Jun 2008 09:32:00 GMT</pubDate><guid>http://www.cnblogs.com/qiubole/archive/2008/06/03/1212941.html</guid><wfw:comment>http://www.cnblogs.com/qiubole/comments/1212941.html</wfw:comment><comments>http://www.cnblogs.com/qiubole/archive/2008/06/03/1212941.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/qiubole/comments/commentRss/1212941.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/qiubole/services/trackbacks/1212941.html</trackback:ping><description><![CDATA[<p>本主题从较高的层次讲述了与邮件安全明确相关的公钥加密元素。此外，还有其他一些资料，您可以参考这些资料，以便更深入地了解该主题。</p>
<p>密码学是一门研究如何通过使用代码和密码来保护信息的学科。密码学形成了邮件安全的基础部分。 </p>
<p>简单来说，编码是系统地更改信息以使其不可读（并无从了解该信息是如何改变的）的过程。最早也是最简单的代码之一（称为恺撒密码）是通过采用字母表并使所有字母移动固定的位数而产生的。发件人和收件人均应了解移动了多少个字母，并因此能够使用该代码来更改信息，从而使他们中的每个人都能够读懂该信息，但其他任何人都读不懂该信息。将信息更改为代码的这一过程称为加密，而将代码重新更改为信息的过程则称为解密。原始邮件称为&#8220;纯文本&#8221;。更改后的邮件称为&#8220;密码&#8221;。用于将纯文本更改为密码的信息称为&#8220;密钥&#8221;。密钥更改信息时所采用的特定方法称为&#8220;算法&#8221;。</p>
<div class="alert">
<table width="100%">
    <tbody>
        <tr>
            <th align="left"><img class="note" src="http://technet.microsoft.com/zh-cn/library/Aa998077.note(zh-cn,EXCHG.65).gif"  alt="" />注意：</th>
        </tr>
        <tr>
            <td>不应将本上下文中的纯文本（或明文）与谈及电子邮件格式时所提到的纯文本混为一谈。在后一种上下文中，纯文本用于区别邮件的 HTML 格式或 RTF 格式。在讨论邮件安全性的上下文中，纯文本用于区别密码，以指出该文本未加密。 </td>
        </tr>
    </tbody>
</table>
</div>
<p>例如，如果发件人希望使用此方法加密邮件，那么发件人需要知道纯文本中的字母 A 的每个实例都将被密钥更改为密码中的字母 D；纯文本中的字母 B 的每个实例都将更改为密码中的字母 E，依此类推。使用此密钥（采用&#8220;将字母前移三位&#8221;的算法），纯文本中的单词&#8220;help&#8221;将加密为&#8220;khos&#8221;密码。 </p>
<p>当收件人收到密码邮件时，需要将它重新转换为纯文本，方法是使用密钥来解密信息，在本例中即是将字母后移三位，从而撤消更改。 </p>
<p>在本例中，发件人和收件人必须将密钥保存在隐秘的地方，因为任何知道密钥的人都可以使用它来解密并阅读邮件。密钥丢失会使得加密变得毫无价值。此外，算法的强度也很重要。未经授权的一方可以获取加密后的密码，并通过根据密码来确定密钥的方法，设法破解加密。 </p>
<p>请注意，发件人和收件人使用的是相同的密钥。此类加密称为&#8220;对称密钥&#8221;加密，因为双方使用相同的密钥。</p>
<p>虽然这只是一个简单的示例，但它说明了密码学的核心概念和功能。密码学最新的进步和提高是逐步产生的。</p>
<div class="MTPS_CollapsibleRegion" id="ctl00_rs1_mainContentContainer_cpe89902">
<div class="CollapseRegionLink" id="ctl00_rs1_mainContentContainer_cpe89902_h"><img id="ctl00_rs1_mainContentContainer_cpe89902_i" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-right-width: 0px" src="http://i.technet.microsoft.com/Platform/Controls/CollapsibleArea/resources/minus.gif"  alt="" />&nbsp;公钥加密的工作原理 </div>
<div class="MTPS_CollapsibleSection" id="ctl00_rs1_mainContentContainer_cpe89902_c" style="display: block; overflow: visible; width: auto; height: auto">
<div class="MTPS_CollapsibleSection" id="" style="border-right: medium none; border-top: medium none; display: block; border-left: medium none; border-bottom: medium none"><a name="sectionToggle0"><!----></a>
<p>1976 年，Whitfield Diffe 和 Martin Hellman 创建了公钥加密。公钥加密是重大的创新，因为它从根本上改变了加密和解密的过程。 </p>
<p>Diffe 和 Hellman 提议使用两个密钥，而不是使用一个共享的密钥。一个密钥（称为&#8220;私钥&#8221;）是保密的。它只能由一方保存，而不能各方共享。第二个密钥（称为&#8220;公钥&#8221;）不是保密的，可以广泛共享。这两个密钥（称为&#8220;密钥对&#8221;）在加密和解密操作中配合使用。密钥对具有特殊的互补关系，从而使每个密钥都只能与密钥对中的另一个密钥配合使用。这一关系将密钥对中的密钥彼此唯一地联系在一起：公钥与其对应的私钥组成一对，并且与其他任何密钥都不关联。</p>
<p>由于公钥和私钥的算法之间存在特殊的数学关系，从而使得这种配对成为可能。密钥对在数学上彼此相关，例如，配合使用密钥对可以实现两次使用对称密钥的效果。密钥必须配合使用：不能使用每个单独的密钥来撤消它自己的操作。这意味着每个单独密钥的操作都是单向操作：不能使用一个密钥来撤消它的操作。此外，设计两个密钥使用的算法时，特意设计无法使用一个密钥确定密钥对中的另一个密钥。因此，不能根据公钥确定出私钥。但是，使得密钥对成为可能的数学原理也使得密钥对具有对称密钥所不具有的一个缺点。这就是，所使用的算法必须足够强大，才能使人们无法通过强行尝试，使用已知的公钥来解密通过它加密的信息。公钥利用数学复杂性以及它的单向特性来弥补它是众所周知的这样一个事实，以防止人们成功地破解使用它编码的信息。</p>
<p>如果将此概念应用于前面的示例，则发件人将使用公钥将纯文本加密成密码。然后，收件人将使用私钥将密码重新解密成纯文本。 </p>
<p>由于密钥对中的私钥和公钥之间所存在的特殊关系，因此一个人可以在与许多人交往时使用相同的密钥对，而不必与每个人分别使用不同的密钥。只要私钥是保密的，就可以随意分发公钥，并让人们放心地使用它。使许多人使用同一个密钥对代表着密码学上的一个重大突破，因为它显著降低了密钥管理的需求，大大提高了密码学的可用性。用户可以与任意数目的人员共享一个密钥对，而不必为每个人单独设立一个密钥。</p>
</div>
</div>
</div>
<div class="MTPS_CollapsibleRegion" id="ctl00_rs1_mainContentContainer_cpe89903">
<div class="CollapseRegionLink" id="ctl00_rs1_mainContentContainer_cpe89903_h"><img id="ctl00_rs1_mainContentContainer_cpe89903_i" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-right-width: 0px" src="http://i.technet.microsoft.com/Platform/Controls/CollapsibleArea/resources/minus.gif"  alt="" />&nbsp;使用公钥加密实现邮件的安全性 </div>
<div class="MTPS_CollapsibleSection" id="ctl00_rs1_mainContentContainer_cpe89903_c" style="display: block; overflow: visible; width: auto; height: auto">
<div class="MTPS_CollapsibleSection" id="" style="border-right: medium none; border-top: medium none; display: block; border-left: medium none; border-bottom: medium none"><a name="sectionToggle1"><!----></a>
<p>公钥加密是邮件安全中的一个基本要素。如果没有公钥加密，那么是否存在实用的邮件安全解决方案是值得怀疑的，因为在公钥加密出现之前，密钥管理是一件很麻烦的事情。在了解了公钥加密的基本概念之后，接下来便是了解如何借助这些概念来实现邮件安全性。</p>
<h3 class="subHeading">公钥加密和数字签名</h3>
<div class="subSection">
<p>前一部分已讨论了，数字签名的核心是能够唯一地标识邮件的发件人。密钥对关系中的互补性本质使得通过公钥加密实现这种唯一标识成为可能。</p>
<p>由于密钥对中的私钥只属于一方，因此，任何时候只要显示已使用了私钥，就可以断定使用该密钥的即是它的所有者。这样，私钥的使用便类似于书面签名，因为只有签名的所有者才真正能够进行该签名。签名代表了它的所有者，就像私钥代表了它的所有者一样。</p>
<p>如果在加密和解密操作中成功地使用了密钥对，那么必定在操作的某个部分使用了密钥对中的私钥。由于公钥仅仅与一个私钥关联，因此可以使用对应的公钥来识别与它相关的唯一私钥。如果在加密和解密操作中成功地使用了特定的公钥，那么可以推断出在操作的某个部分使用了对应的私钥。因为只有密钥所有者可以使用私钥，所以，这意味着只有密钥所有者能够执行加密和解密操作中的特定部分。 </p>
<p>使用私钥确定身份说明已成功地完成整个加密和解密操作。完整的操作意味着必须使用私钥将纯文本加密成密码，然后使用对应的公钥将密码重新解密成纯文本。如果显示此操作已成功完成，则说明使用了私钥，并且仅使用了私钥。</p>
<p>要说明已成功执行了加密和解密操作，那么加密和解密操作前的纯文本必须与加密和解密操作后的纯文本匹配。必须直接对两组纯文本进行比较，并且必须显示两者完全匹配。必须存在一个用来进行比较和验证的控件。 </p>
<p>在电子邮件中，此控件就是实际的邮件。由于邮件对于发件人和收件人而言均可用，因此是一个很方便的控件元素。 </p>
<p>若要在此比较操作中使用邮件，需要对邮件进行&#8220;哈希&#8221;转换，即将其全部文本转换成数字形式。完全相同的邮件文本将生成完全相同的哈希值。</p>
<p>通过在发送时获取邮件的哈希值并将它与私钥组合在一起，私钥的所有者就能够证明是他或她发送的该邮件。 </p>
<p>将邮件与私钥组合是通过使用发件人的私钥加密哈希值（创建实际的数字签名）来完成的。根据发件人电子邮件系统的配置，数字签名将附加到邮件的底部（创建&#8220;明文签名&#8221;邮件），或者与原始邮件组合成一个二进制附件（创建&#8220;不透明签名&#8221;邮件）。 </p>
<p>由于明文签名邮件的数字签名作为附件添加到原始邮件中，因此不支持 S/MIME 的电子邮件客户端能够阅读此类邮件。非 S/MIME 客户端将丢弃签名并显示原始邮件。但是，无法对邮件进行验证；它本质上与未签名的邮件相同。明文签名邮件的缺点是：干预邮件网关以改变邮件，从而使签名无效的可能性越来越大。 </p>
<p>相反，在不透明签名邮件中，由于邮件和数字签名被视为一个二进制附件，因此在传送过程中不太可能被改变。但是，只有 S/MIME 客户端能够阅读该附件。如果非 S/MIME 客户端收到了不透明签名邮件，该邮件将是不可读的。</p>
<p>在某种程度上，创建不透明签名邮件是为了解决以下电子邮件系统问题：即电子邮件在传送过程中邮件正文发生改变。在此应当指出的是，遵守 S/MIME 标准的当前电子邮件解决方案不会改变邮件正文。不过，有许多客户端无法阅读不透明签名的电子邮件。因此，建议您发送明文签名的邮件。 </p>
<p>当收到邮件时，可以检索数字签名，并在解密操作中应用发件人的公钥，从而产生出邮件的原始哈希值。然后，可以将此哈希值与收到的邮件的哈希值进行比较。由于只有一个私钥可以与公钥对应，并且只有公钥的所有者能够用它来成功地加密哈希值，因此使用公钥解密哈希值意味着加密该哈希值的是私钥的所有者。由于哈希值是邮件文本的数字表示形式，因此，如果加密的哈希值与已收到邮件的哈希值匹配，则意味着发送的邮件文本与收到的文本匹配。考虑到只有私钥所有者能够发送该邮件，因此结果便是收件人确信只有密钥所有者发送了该邮件，从而提供了身份验证，并因此而提供认可功能。它还显示出邮件未被更改，从而提供了数据完整性。如果哈希值不匹配，那么收件人便知道邮件在传送过程中被改变，或者所使用的公钥与所使用的私钥不匹配。在这两种情况下，收件人知道邮件无效，不应信任。</p>
<p>因此，可以看出公钥加密是通过什么途径提供组成数字签名的安全服务。</p>
<p>下图显示在添加了公钥加密的支持元素的情况下进行签名的顺序。 </p>
<div><strong>
<p>
<p>公钥加密以及电子邮件的数字签名</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Aa998077.35451fb8-5e11-4d67-ba6e-e5d4da6febca(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>捕获邮件。<br />
    <li>计算邮件的哈希值。<br />
    <li>检索发件人的私钥。<br />
    <li>用发件人的私钥加密哈希值。<br />
    <li>将加密的哈希值作为数字签名附加到邮件中。<br />
    <li>发送邮件。<br />
    </li>
</ol>
<p>下图显示在添加了公钥加密的支持元素的情况下进行验证的顺序。 </p>
<div><strong>
<p>
<p>公钥加密以及验证电子邮件的数字签名</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Aa998077.d1b14a27-5cfb-4df2-89f7-990219378716(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>接收邮件。<br />
    <li>从邮件中检索包含加密哈希值的数字签名。<br />
    <li>检索邮件。<br />
    <li>计算邮件的哈希值。<br />
    <li>检索发件人的公钥。<br />
    <li>用发件人的公钥解密加密的哈希值。<br />
    <li>将解密的哈希值与接收邮件时产生的哈希值进行比较。<br />
    <li>如果值匹配，则说明邮件有效。<br />
    </li>
</ol>
<p>该序列操作显示了公钥加密如何提供必要的功能，以使数字签名具备其核心的安全服务：身份验证、认可和数据完整性。</p>
</div>
<h3 class="subHeading">公钥加密和邮件加密</h3>
<div class="subSection">
<p>与数字签名不同，公钥加密和邮件加密之间的关系通常更为简单，因为加密是公钥加密的核心功能。但是，邮件加密不仅是通过使用密钥对来加密和解密邮件而完成的。密钥对用于邮件加密中，而不用于整个邮件。</p>
<p>由于邮件加密的目的是确保只有已经授权的收件人能够查看邮件，因此每个收件人的私钥都适合于提供该服务。由于只有私钥所有者能够成功地使用私钥，因此在阅读邮件的过程中使用该密钥确保了只有该密钥的所有者能够阅读该邮件。此功能提供了作为邮件加密基础的保密性。此外，由于公钥可以广泛地分发，因此它使得任意数目的人都可以向一个私钥持有者发送信息。</p>
<p>但是，密钥对不是用在整个邮件中。这是因为，由于密钥算法所必需的复杂性，从而使得使用密钥对进行加密和解密操作是一个昂贵的过程。虽然需要使用密钥对，但它不是必须用在整个邮件中。它需要成为信息&#8220;锁定&#8221;和&#8220;解锁&#8221;过程中的一部分。只要在提供私钥前邮件不可读，便满足邮件加密的目的。</p>
<p>本主题前面的&#8220;公钥加密的工作原理&#8221;已提到，公钥使用强算法来弥补它广为人知这一特性。这些强算法意味着它们比原来的对称密钥更大，因此使用它们进行计算的速度也更慢。由于私钥仅仅用于在查看信息之前解锁信息，而不是用在整个邮件中，因此，确保在提供私钥之前信息不可用的同时，对尽可能少的信息使用密钥对、而对尽可能多的信息使用速度更快的对称密钥则更为经济一些。</p>
<p>对称密钥使用一个双方必须都知道的密钥。此过程有时称为&#8220;密钥协商&#8221;。如果使用密钥对，则没有密钥协商过程，因为一个公钥可以被许多人使用。密钥对还可以与对称密钥配合使用，以实现密钥协商。可以选择对称密钥，并且可以使用密钥对的公钥对该密钥进行加密，然后将其发送给私钥的所有者。当发送给多个收件人时，可以对所有收件人使用该对称密钥，然后使用每个特定收件人的公钥对该对称密钥进行加密。由于只有私钥所有者可以解密对称密钥，因此对称密钥对于未经授权的人而言仍然是保密的。可以在特定的操作或会话期间生成用于一次性使用的对称密钥。这种对称密钥称为&#8220;会话密钥&#8221;。公钥加密可以增强对称密钥加密的效应，而不是将其取而代之。</p>
<p>邮件加密的目标是确保在出示私钥之前，邮件不可读。在对称密钥协商中可以使用私钥，以便安全地传送对称密钥。由于可以安全地将对称密钥传送给收件人，因此，可以使用对称密钥加密邮件，然后使用密钥对中的公钥加密该对称密钥。只有私钥持有者可以解锁对称密钥，然后使用解锁后的对称密钥解密邮件。此操作的作用就好像使用密钥对对整个邮件进行加密和解密。但是，由于它对大多数信息使用速度更快的对称密钥，因此此操作比其他操作方法的速度要快。在此过程中，邮件在出示私钥之前一直处于被保护状态，从而提供了保密性，这是邮件加密的基本服务。由于加密和解密过程，在加密后改变邮件会导致解密操作失败，从而提供数据完整性。</p>
<p>虽然人们通常都想不到使用对称密钥，并且它的优势不会立即就显示出来，但是它可以在不损失邮件安全性的情况下提高邮件加密的速度，从而增强了邮件安全性。下图显示在具有公钥加密的支持元素的情况下进行加密的顺序。 </p>
<div><strong>
<p>
<p>公钥加密以及电子邮件的加密</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Aa998077.21058391-2d70-42f9-bf25-8ead79705b27(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>捕获邮件。 <br />
    <li>检索收件人的公钥。<br />
    <li>生成一次性对称会话密钥。<br />
    <li>用会话密钥对邮件执行加密操作。<br />
    <li>用收件人的公钥加密会话密钥。<br />
    <li>加密的会话密钥包含在加密的邮件中。<br />
    <li>发送邮件。<br />
    </li>
</ol>
<p>下图显示在添加了公钥加密的支持元素的情况下进行解密的顺序。 </p>
<div><strong>
<p>
<p>公钥加密以及解密电子邮件</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Aa998077.50f0afca-e520-46b5-8e12-6e295dfe86d9(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>接收邮件。<br />
    <li>从邮件中检索加密的邮件和加密的会话密钥。<br />
    <li>检索收件人的私钥。<br />
    <li>用收件人的私钥解密会话密钥。<br />
    <li>用解密的会话密钥解密邮件。<br />
    <li>将未加密的邮件返回给收件人。<br />
    </li>
</ol>
<p>这一系列活动显示出公钥加密如何为邮件加密的下列核心服务提供支持：保密性和数据完整性。</p>
</div>
<h3 class="subHeading">了解如何将公钥加密同时用于数字签名和邮件加密</h3>
<div class="subSection">
<p>数字签名和邮件加密是倍受赞誉的服务。在考虑如何将公钥加密分别用于每个服务后，考虑这些服务如何一起使用会对您有所帮助。</p>
<p>下图显示在添加了公钥加密的支持元素的情况下进行签名和加密的顺序。 </p>
<div><strong>
<p>
<p>公钥加密以及对电子邮件进行数字签名和加密</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Aa998077.e81cca9b-c780-49d9-a3f9-69cc3c442183(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>捕获邮件。<br />
    <li>计算邮件的哈希值。<br />
    <li>检索发件人的私钥。<br />
    <li>检索收件人的公钥。<br />
    <li>用发件人的私钥加密哈希值。<br />
    <li>将加密的哈希值作为数字签名附加到邮件中。<br />
    <li>生成一次性对称会话密钥。<br />
    <li>用会话密钥对邮件执行加密操作。<br />
    <li>用收件人的公钥加密会话密钥。<br />
    <li>加密的会话密钥包含在加密的邮件中。<br />
    <li>发送邮件。<br />
    </li>
</ol>
<p>下图显示在添加了公钥加密的支持元素的情况下对数字签名进行解密和验证的顺序。 </p>
<div><strong>
<p>
<p>公钥加密以及解密电子邮件和验证数字签名</p>
<p>&nbsp;</p>
</strong><br />
<img alt="" src="http://technet.microsoft.com/zh-cn/library/Aa998077.97705e57-0a94-4197-99c3-40bb58a9eaa0(zh-cn,EXCHG.65).gif" /></div>
<ol>
    <li>接收邮件。<br />
    <li>从邮件中检索加密的邮件和加密的会话密钥。<br />
    <li>检索收件人的私钥