公钥安全机制与宫爆鸡丁的故事

你有没有在网上买过东西?没?什么?哦,怕不安全。php

如今信息科技突飞猛进,貌似一转眼的功夫,交电话费、考试报名、逛图书馆、订购午餐都搬上了互联网。方不方便且不说,单说足不出户能叫到午餐,这要在之前那可都是科幻小说啊。只不过科幻小说里,主人公可能只须对机器人吩咐说,“来份宫爆鸡丁盖饭,外加一碗紫菜鸡蛋汤”,一切就搞定了——哪像如今这样,装五花八门的杀毒软件,还得随时当心钓鱼网站的陷阱。那如今的互联网真的如此危险么?先看看大宝的此次订餐经历,您再下结论也不迟。node

话说大宝一日宅在家中,百无聊赖地度过了阴雨连绵的上午,突然感受腹中空虚,四肢无力——他明白了,原来本身是饿了。闲话少说,大宝奔到电脑前,准备给本身淘一顿午餐。算法

飘过了几家附近的餐馆以后,大宝决定在“啃的鸡”点一份宫爆鸡丁盖饭套餐。点完菜,服务员小姐礼貌地将大宝带到了收银台——这“啃的鸡”是先付账、再上菜的。ubuntu


传说中的宫爆鸡丁
(传说中的宫爆鸡丁。来源: princeroy, cc-by-2.0)

若是互联网上也能够用现金买单就行了,那么“啃的鸡”也不用再多花冤枉钱,聘用专业的银行交易专家来收银了。惋惜现实每每跟理想相反,坐在收银台里的,正是传说中的银行交易专家:致富宝。“致富宝”做为专业的支付中介,能很是熟练地处理各类银行业务——无论是招行信用卡,仍是农行借记卡,他都能应对自如。segmentfault

就在这个时候,大宝突然发现,带他来的服务员小姐溜回“啃的鸡”铺子里忙其它事儿去了,这“致富宝”原来是街边的一个小摊。再看这位摊主,正拿着宫爆鸡丁的单子,对着大宝得意地笑。大宝顿时惊出一身冷汗。浏览器

“糟糕!上当了!”安全

“大哥,这宫爆鸡丁儿不是你点哩?”摊主口音挺重。服务器

“是却是——你就是那个什么什么……银行交易专家?”大宝半信半疑。函数

“那能假了啊!你看看,工行农行中行建行……”摊主不高兴了。测试

“得得得,你要是个钓鱼的,也照样这么说。”大宝摆事实、讲道理,“营业执照给我看看,是真的就行。”

钓鱼 是指一些小商小贩,冒充本身是某支付平台或银行,骗取大众钱财的手段。

“俺哪敢掉你的鱼啊!”摊主边说,边从口袋里掏出一份证书,“你验验,这能假了不,这会儿打(假)的正严哩。”

这份证书可不是通常的营业执照。在数字世界里,光一个红红的公章印,说明不了什么问题。互联网上的电子证书,不只包含一些基本信息如“摊主姓名”、“工做单位”、“邮政编码”等,还包含一把很重要的钥匙,和一个很重要的签名。

先说这把钥匙吧。其实这种钥匙是成对儿的,证书里面嵌的这把,叫作公钥;另外一把由摊主保管,叫作——母钥?其实挺合理的,配对嘛——正确的叫法是私钥。从名字也能够看得出来,公钥是公开的,你们均可以拿来用;而私钥是我的保管的,好比摊主的这把私钥就由他我的保密持有,别人谁也拿不着。

这里,配对的两把钥匙之间是有数学相关性的,那这是怎样一种相关性的?用传说中的 RSA 算法举个例子吧,两把钥匙看上去是三个很是大(至少应该是,大的难破解嘛)的数字——私钥是 (7, 10),公钥是 (3, 10)

那这钥匙是怎么算出来的呢?

先选种子,随机选两个很是大的 素数 。在这个例子中,我选的是 25,但实际应用中应该越大、越没有规律越安全。这个时候,钥匙对中的公共部分 10 就算出来了:2 x 5 嘛。接着,3 也不难找——随便挑一个跟 (2 - 1) x (5 - 1) = 1 x 4 = 4 互质 的、且比 4 小的数就能够了—— 34 无法被同一个比 1 大的数除开,这样一来,咱们的公钥 (3, 10) 就定下来了。接下来算私钥,这个稍微麻烦一点点,就是要找一个乘以 3 的积除以 4 的余数恰好等于 1 的数字——我选了 7,由于:7 x 3 mod 4 = 21 mod 4 = 1(这里的 4 仍是前面 (2 - 1) x (5 - 1) 算出来的那个 4)。用数学点儿的话写下来,就是:

  1. 随机地选择两个很是大的素数 pq,好比 25
  2. 密钥对的公共部分就是 N = pq,就是例子中 N = 2 x 5 = 10
  3. 算出一个中间数 M = (p - 1)(q - 1),好比 M = (2 - 1) x (5 - 1) = 1 x 4 = 4
  4. 选择一个小于 M,且与 M 互质的数 e,好比 e = 3
  5. 根据 d x e mod M = 1 算出 d,好比 d = 7 由于 7 x 3 mod 4 = 1
  6. 烧掉全部写着 pq 的打草纸——由于“不烧不专业”嘛。
  7. 而后呢,公钥就是 (e, M),或者简单说 3 也成,对应的私钥就是 7,而 10 是公共部分。

那这两把钥匙有什么用呢?咱们仍是先来作两道简单的数学题。

第一题,83 次方整除 10 的余数是多少?八八六十四,64 乘以 8,这个 64 乘以 8 ……很差算是吧,没事,这个例子能够偷点懒——只算个位数,反正不是要整除 10 么。8 x 8 = 644 x 8 = 32,结果就是 2 呗。

第二题,(用第一题的结果)27 次方整除 10 的余数是多少?2 x 2 = 44 x 2 = 88 x 2 = 166 x 2 = 122 x 2 = 44 x 2 = 8 ——数清楚了没,是 7 个不?结果正是 8

没错,第二题的结果恰好是第一题里面的 8。这是一个巧合,仍是一个愚人节玩笑?都不是,这是用数学方法证实过的(请见下面的分割线中间的部分),若是算出来不是 8 才是开玩笑呢。第一题中,咱们其实用公钥 (3, 10)8(个人银行卡密码,请勿模仿)给加密了——加密成了 2;第二题,咱们又用私钥 (7, 10),把加了密的密码给解出来了。


二战德国所使用的的洛伦兹密码机
(二战德国所使用的的洛伦兹密码机。图片来源: wikimedia

有那么点意思了,是吧。这样一来,我就能够用密文的 2 来代替明文的 8,放心地将密码告诉拥有私钥的人。即便密码中途被别人截获了,没有私钥的骇客依然没法取得个人密码。

有兴趣的话,您能够把公私钥匙调个个儿,再用相同的办法算一遍——也就是用 7 加密、用 3 解密,结果是同样能够还原的。可是反过来以后,若是我仍是加密银行卡密码的话,个人智商就值得研究了——做为公钥的 3 是全部人都知道的,也就是说全部人都能解密获得原文,我根本用不着费事算来算去,直接把密码告诉你们就得了呗。这么作真的没有意义么?非也,这其实正是签名和验证。好比说,用 (3, 10) 是没法正确解密(验证)一段用 (5, 17) 加密(签名)的数据的,也就是说,“解铃仍须系铃人”,要想验证一个签名,只能用跟“签名用的私钥”对应的那一把公钥。而从理论上来讲,私钥是我的保密持有的,因此咱们能够经过解密的测试,来验证一段信息确实是原本来本地来自拥有私钥的人,而这我的也没法抵赖说“根本没这么回事儿”。

除非他把私钥弄丢了,别人捡了去。这通常状况下是有补救措施的——挂失嘛,钥匙丢了换锁呗。可是若是你根本不知道钥匙丢了,那就没辙儿了。好比说,既然 310 你们都知道了,若是什么人背地里偷偷算出了这个 7,那岂不是千里之堤,溃于蚁穴?

没必要担忧。

问题就在于,这个梁上君子打算怎么把 7 算出来。最直接也是最容易想到的办法,就是先将 10 分解成两个质因数 25,而后照前面的算法来算 7。这是惟一的办法吗?很遗憾,目前尚未人从数学上证实这是惟一的办法。为何有人会去试图证实,这是惟一的办法?由于,他们还没找到其它更好的办法。恰巧,这个分解质因数的办法很是难。

由于打草纸烧掉了,因此理论上说,暂时没有别人知道 10 是由哪两个素数相乘获得的,通常状况下,算这个题的人(或是机器)也会很快忘掉这两个素数。虽然要破解前面的例子简单了点,可是有种你口算个一百来位的试试,呵呵。这也被相信是 RSA 算法的安全保障——对于很是大的数字,分解出两个质因数是很是困难的。这个结论目前尚未人证实,但也没有人证实它不困难。尽管你们说法不一,可是有一点是确定的——数字越大越难算。有多难呢?1999 年计算机花了五个月的时间,解出了一个并不算很大的(512 bit)N 的两个质因数;而当 N 成倍增加时,破解的时间能到成百上千年——等到破解出来的时候,加密保护的信息可能早就不是秘密了。听说有人证实用量子计算机,能够在可观的时间里,破解更大的数字。看来一旦量子计算机成为现实,RSA 就要下课了——惋惜眼下量子计算机不通(更新:质疑声中的 D-Wave 量子计算机已经诞生了),再加上咱们选用的数字很是大,因此想简单地“把 10 分解成 2 x 5”,那是不可能的。

因而,要根据公钥 3 算出私钥 7 来,就几乎是不可能的了。因此,摊主能够安心地将公钥嵌在证书里,公之于众。例子中的 RSA 看似牢不可破,但现实中还须要许多的辅助手段,来进一步保证它的安全性。何况世界上也不是就 RSA 一家呀,因此嘛,这种公钥加密算法仍是挺让人放心的。

总结一下了:“解铃仍须系铃人,系铃定是解铃人”(下半句我瞎掰的)。公钥、私钥都是一对儿一对儿的;要解密由公钥加密的数据,仅能够用对应的私钥;要验证由私钥签名的数据,仅能够用对应的公钥。这种“一个加密另外一个解”的算法,通常就被形象地叫作“非对称加密算法”,这俩把密钥也被叫作“非对称密钥”。

若是这尚未知足您浓厚的数学兴趣的话,您能够继续阅读下面这段。(摘自维基百科,RSA加密算法的操做——不过貌似英文版更详细一点点)


==========哦美丽的分割线==========

公钥和私钥的产生

假设 Alice 想要经过一个不可靠的媒体接收 Bob 的一条私人讯息。她能够用如下的方式来产生一个公钥和一个密钥

  1. 随意选择两个大的素数 pqp 不等于 q,计算 N=pq
  2. 根据欧拉函数,不大于 N 且与 N 互质的整数个数为 (p-1)(q-1)
  3. 选择一个整数 e(p-1)(q-1) 互质,而且 e 小于 (p-1)(q-1)
  4. 用如下这个公式计算 dd × e ≡ 1 (mod (p-1)(q-1))
  5. pq 的记录销毁。
  6. e 是公钥,d 是私钥。d 是秘密的,而 N 是公众都知道的。Alice 将她的公钥传给 Bob,而将她的私钥藏起来。

加密消息

假设 Bob 想给 Alice 送一个消息 m,他知道 Alice 产生的 Ne。他使用起先与 Alice 约好的格式将 m 转换为一个小于 N 的整数 n,好比他能够将每个字转换为这个字的 Unicode 码,而后将这些数字连在一块儿组成一个数字。假如他的信息很是长的话,他能够将这个信息分为几段,而后将每一段转换为 n。用下面这个公式他能够将 n 加密为 c

n^e==c(mod N)

计算 c 并不复杂。Bob 算出 c 后就能够将它传递给 Alice。

解密消息

Alice 获得 Bob 的消息 c 后就能够利用她的密钥 d 来解码。她能够用如下这个公式来将 c 转换为 n

c^d==n(mod N)

获得 n 后,她能够将原来的信息 m 从新复原。

解码的原理是:

c^d==n^(e*d)(mod N)

以及 ed ≡ 1 (mod p-1)ed ≡ 1 (mod q-1)费马小定理证实

n^(e*d)==n(mod p)n^(e*d)==n(mod q)

这说明(由于 pq 是不一样的素数

n^(e*d)==n(mod p*q)


==========哦快乐的分割线==========

好了,回到咱们饥肠辘辘的大宝的故事来吧。

“我如今验证一段话,若是你能解出来,就算这营业执照是你的吧。”大宝说着掏出一张白纸,背着摊主在纸上胡乱写下几个字——“戈壁滩上打酱油”。

大宝从证书中取出钥匙——也就是公钥了,再在纸上这么一比划,“戈壁滩上打酱油”几个字儿顿时被加密成 0101110...(篇幅所限,此处略去上千个 0、1)...1010101。

“给你,试试吧。”

“我说是个人就是个人,”摊主从怀里摸出一把旧钥匙(私钥,固然要藏好了),又在纸上一比划,“那还能错的了了!”

0 和 1 渐渐隐去,“戈壁滩上打酱油”几个字儿又冒了出来——解密验证成功,大宝无言以对,只得认可证书里的公钥的确是摊主本人的,除非摊主从真全部者那里抢的私钥。

“好吧,就算这证书是你的吧。那你凭什么说,你就是证书上写的,”大宝撇了一眼营业执照,“什么致富宝什么的?”

大宝说的没错,每一个人均可以伪造证书,就算这公钥确实属于他又能何如。

“这买卖真难作!我不干了!”摊主这回真的急了。

“你不干了,我还要吃饭呢!”大宝也急了,二话不说把摊主拉到了工商局——颁发营业执照的公信机构。(可见,吃饭对大宝来讲是多么重要)

到了工商局,办事员业务很是熟悉。

“证书真伪辨别是么,请出示证书。”

办事员拿着手持式扫描仪一扫,证书复印件就叮叮当当地出如今一旁的打印机中。只见他操起一把大剪刀,对着复印件“咔嚓”就是一刀,将证书拷贝一份为二。要不说他业务熟悉么,这一刀不偏不倚,刚恰好把前面提到过的电子签名部分剪了下来。

要说这电子签名是啥,还得先说这证书是怎么签发的。


证书是怎样炼成的
(证书是怎样炼成的——最右边 OK 的那个。图片来源:OpenClipart.org,GFDL)

当初“致富宝”开道创业的时候,写过一份营业执照申请函,内容就是如今这剪下的两半中,比较大的那一半——电子签名是小半。工商局在评审了申请函以后,准予营业,因而签署了这一份证书,而证书中的电子签名正是官方签署的证据。

这到底仍是公钥和私钥的讨论。话说工商局本身也有一对儿密钥,专门用来签署营业执照。当申请函获得批准的时候,办事员用工商局专用私钥在申请函上一比划,这申请函就被“加密”成了一段电子签名,也能够说,工商局在申请函上签名批准了。请注意,这申请函里到底包含什么呢?正如前面提到过,基本信息是必须有的,另一个很重要的部分就是申请者——或者叫摊主——的公钥。毕竟公钥也是一种数据嘛,看成申请函数据的一部分来加密了。别弄浑了哦,办事员用工商局的私钥,加密了包含有摊主公钥的申请函,制做成了摊主证书的电子签名部分。这工商局的私钥但是公信机构独有的,日常要锁在很大的保险柜里的,因此签署出来的证书才是真的。

那咱们就看看下一步,办事员怎么来辨别真伪吧。

“这是咱们工商局的公钥,你们能够免费索取的。”办事员从柜台里搬出一箱子钥匙,说。

“那照这么说,有了这个,”大宝捡起一枚钥匙说,“我本身也能辨别真伪咯。”

“没错。”办事员也拿起一枚钥匙,在电子签名那一半上一比划,龙飞凤舞的电子签名乎的一下,变成了一份申请函的模样。

“哎哟,好像不对哦。”办事员拿过剪下的大半,跟刚解密出来的申请函一比,“这哪是致富宝啊,明明写的是致富堡嘛。”

大宝四下一看,那山寨摊主早逃之夭夭了。真是虚惊一场,好歹大宝没有把钱给了那钓鱼的山寨摊主。

理论上,假的电子签名是不可能解密成跟原文仅一字之差的——其实是什么都解不出来的,只有真的签名才能解出原文来。另外为了减少数据量和其它考虑,原文在签名以前,作过摘要处理。故事中作了一些简化,特此声明。另外,虽说两种密钥均可以加解密,但专业地来讲,公钥是用来作加密和验证的,私钥是用来作解密和签名的。

若是您拥有一份“我的电子证书”,那么您也能够用您的私钥签署数据——好比发电子邮件,那么收到信的人均可以用您证书中的公钥进行验证,以确认信件确定是您亲笔签署的;反之,若是您的朋友有一份电子证书,那么您就能够很放心地用公钥加密一些只有您朋友能够阅读的数据,而后安全地经过您不信任的传播媒体——好比互联网——传递到您朋友的手中。电子签名在必定程度上,还保证了数据的完整性和不可抵赖性。


一封给大宝的签名信
(一封给大宝的签名信,计算机能够验证其中的 PGP 签名)

后面发生的事情,就是大宝跟他验过真身的“致富宝”隔着一条河交易的过程了。没错,我是说隔着一条河——这个城市彷佛忘记修桥了,大宝只能扯着嗓子喊,把他的银行卡密码告诉“致富宝”才行。如今互联网啊,真是危机四伏,你说那个路由节点上没趴着成群结队的嗅探器的(夸张手法,请保留意见)。要是大宝真个把密码喊出来,那没等他吃完饭,卡里的钱就全没了。因此咧,大宝就跟“致富宝”商量了一个办法。

这个办法固然就是加密咯。大宝想用对方的公钥加密本身的密码,而后“喊”过去,对方解密出来就搞定了。但问题是,大宝的数学实在是太差了,要算乘方的话,手指头根本不够他掰的。何况,要加密的也不只仅只是 6 位密码,还有像“中国农业银行青岛市分行麦岛支行”这样的银行名,还有很长的银行卡号,更是还有大宝的大名——大卫/阿基米德/宝兰德/罗纳尔迪尼柯夫斯基。要让他把这些都加密算出来,非把他饿死不可,非对称加密算法并不适合于大批量的数据加密。因此,大宝想出了另外一个办法——对称加密算法

说白了,就是用同一个,也是惟一一个密钥作加密解密的算法。缘由么,简单呗。好比说,银行卡密码仍是 8,那么加密就是 8 x 9 = 72,解密就是 72 / 9 = 8,这里的 9 就是对称密钥。

这种办法的缺点很明显,在双方进行加密通讯以前,必须得先商量好一个对称密钥。而且一旦这个对称密钥丢了,那么全部数据都不安全了。像大宝这样隔着一条河,大声地告诉对方“喂~密钥是 9!你除以 9 就好了!”,无异于直接把密码告诉守在一旁的骇客

大宝也不笨。9 做为对称密钥,不也是串儿数据么,反正也不长,用刚才想用的“非对称加密算法”,加密了再喊过去就是了呗,问题解决。

可是,这单单一个 9 实在是太好猜了,骇客只须认得九九表,就能一个一个地试出来。相比于用成百上千年才能破解的“非对称密钥”,数到九九八十一简直就是一眨眼的功夫。

不过要么怎么说“魔高一尺,道高一丈”呢,大宝有的是锦囊妙计。他把密码、银行名、卡号、持卡人姓名拼在一块儿,再随机分红一小份儿一小份儿的,而后用不一样的对称密钥,分别加密。这样就增长了破解的难度,即便骇客破解出其中的一部分,也没法获得足够的信息去盗取钱财。而实际中,还有更多的锦囊来保证信息的安全。

因而,咱们就看到大宝为了买到他的宫爆鸡丁,开始了 0 和 1 的传输。他先随便定下了一个对称密钥,而后用“致富宝”证书的公钥对其加密并传给对方;等对方解密出同一个对称密钥以后,大宝开始用对称算法加密传输数据;过了 1 分钟,暂停传输,从新定一个新的对称密钥,重复上述过程,直至数据所有传输完成。顺便说一句,这种为了安全和效率的综合考虑,混合使用对称算法和非对称算法的方法,叫作“数字信封”机制,像 HTTPSSSH/SFTP,以及选择使用 SSL/TLSIRCIMAP 等协议,都是采用相似的这种机制实现的。

密码正确,确认付款,大宝终于吃到了他的宫爆鸡丁,故事也到此告一段落了。可是现实生活中,若是您在网上交易的时候,应该怎么作,才能保证数据的安全呢?

首先,您能够仔细观察浏览器的地址栏,若是是像“https://fantix.org”(更新:域名已失效)这样以 https 打头的地址,那么您能够相信,至少这个地址采用了上述公钥办法作验证,而且全部数据都是加密传输的;不然若是是像“http://fantix.org”这样的 http(没有 s)打头的,就彻底没有公钥私钥这一说,更没有身份验证的机制(只是说传输协议上没有保证,不表明不经过其余方法进行加密或验证),而且,发送未加密的数据就如同在互联网上“喊”同样,至关危险。


个人网站
(个人网站已经加密,但貌似个人证书不是那么可信……)

其次,通常浏览器像 FireFox,都会自动验证服务器证书的真伪,好比域名是否相符,是否在有效期内等。而且通常浏览器内嵌了不少公信机构 CA 的证书(公钥),您不须要本身跑到工商局去,浏览器会搞定的。一旦发现有冒名顶替者,必然会弹出大字儿,提醒您不要上了钓鱼网站的当。(广告!FireFox 还能够辨识钓鱼网站,如您不慎勿入其中,则 FireFox 将用醒目的红字儿来警示您。)

在 FireFox 3(更新:如今已经出到了 Firefox 27) 中,若是您浏览的页面被公信机构验证是货真价实的,证书合法有效,那么地址栏中“https”前面应该是绿色的,点击它能够看到经营者信息;若是数据仅仅是加密过,不会被第三方窃听到的话,“https”前面的图标背景是蓝色的(如上图);而对于普通的“http”协议,背景是没有特殊警示颜色的,好比在个人 Ubuntu 中,它是灰扑扑的。

补充说明,咱们只谈了公钥安全机制,但并非说绿色的标志就必定安全——好比说一些木马就是最大的威胁。因此,若是您使用木马和病毒比较多的操做系统——好比说 Microsoft Windows 的话(尤为是怕黑屏,没有及时更新的盗版系统),我仍是建议您,不要由于 FireFox 3 的绿色标志,就把杀毒软件、杀木马软件卸载掉。

这就是公钥安全机制与宫爆鸡丁的故事了,更流行的叫法是 PKI(Public-key Infrastructure, 公钥基础设施),包括一沓子算法、协议,还有一整套公信机构 CA(Certificate Authority,身份认证机构)的官僚体系。没准过不了多久,咱们就会人手一份我的电子证书,连身份证都免了。

版本历史:
2014.2.18 - Markdown 版,增长了更新注释。
2009.4.19 - 发布在 http://songshuhui.net/archives/12755。 2009.4.14 - 修改了靠后面,先后不一致的一点点。添加图片、连接。排版。 2009.4.13 - 整理细节。 2009.4.7 - 替换了说理的那段,整理了一下逻辑,完善了论据。 2009.4.3 - 用真正的例子,替换掉了原来一个很白痴的例子。其余有微小改动。 2009.4.2 - 初稿完成。

相关文章
相关标签/搜索