前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >永强接着教你加解密:非对称篇(四)

永强接着教你加解密:非对称篇(四)

作者头像
老李秀
发布2019-11-12 23:08:18
4200
发布2019-11-12 23:08:18
举报

大家好,我是老李,下面是我想说的话:

  • 首先这是一篇本应该发布在春节后的三个月前文章
  • 文章封面图是永强自己选的

大家好,我是许久未露面投稿的永强,下面是我想说的话:

  • 虽然过年我没有收到压岁钱
  • 但是我过年也没有收到任何年终奖

别人背地里都这么跟我说:永强啊,你的文章都是老李那里难产时候上去顶包凑数量的,阅读量不超过50!

MD,净说实话

我最近去搞工业机器人这件事情是一件人尽皆知(包括老李在内的好几个人都知道)的事情,没有了老王公司的氛围,我的生活和学习的乐趣都快没了。一天天净对着不长眼的机器人瞎折腾,那玩意程序一弄不好就跟没头苍蝇似的做布朗运动。

布朗运动...???...怎么听着这么耳熟?

好了,言归正传,我准备开始充数了。

其实过年期间我就给上高中、初中的少年一代用加解密技术装了一波儿大逼,一点儿都不出乎预料:

根本没人鸟我

让我感到惊讶的是,他们这些人一天天除了斗地主就是王者荣耀,一天天抱着个手机跟特么屎壳郎滚粪球子似的,我上去问个质数、合数竟然都特么忘记了,让我感到十分欣慰。

没想到除了西方国家的财富外,属于全人类的知识也会两极分化

其实今天的话题和质数真的有关系,如果你要也不知道质数是什么了,趁着过年还在老家,赶紧去找你小学数学老师去问问,然后你就可以精通质数了。

非对称加解密的典型代表就是RSA,而且RSA用的最广泛最多,所以,实际上这篇就是来普及RSA的。我本来想起一个类似于《论RSA的音容笑貌和尺寸长短》这样的标题,不过老李不让,他说这样会破坏标题的队列感和仪式感,同时也会让本篇文章产生孤独感,破坏风水。

实际上RSA算法都是公开的,算式都是公开了,任何一个人都可以从互联网上查阅到这个公开算法过程是什么:

代码语言:javascript
复制
密文 = 明文^E mod N明文 = 密文^D mod N

以上就是RSA加密和解密的过程,就是这么简单粗暴。只要上过学,就知道上面算式是什么意思。

在下面的课程开始前,请事先了解一下如下几个名词的含义:

  • 质数
  • 最大公约数
  • 最小公倍数
  • mod,即余数

好了,我开始准备数学实战演练RSA算法的数学计算过程了:

  • 准备两个随机的质数p和q,其中p=13,q=17,然后令N=p*q,即N=221
  • 令L为p-1(12)和q-1(16)的最小公倍数,即L=48
  • 有数字E,E需要满足如下条件:1 < E < L(L=48)、E和L最大公约数为1,我凭信仰选了一个5
  • 有数字D,D需要满足如下条件:1 < D < L、E * D mod L = 1,所以,这个很简单,可以求出D=29(怎么求的自己去算)
  • 所以N=221,L=48,E=5,D=29

所以,请记住:

{E,N}即{5,221}就是公钥,{D,N}即{29,221}就是私钥

那么,我们将这两个数字代入到RSA加密和解密的工程中去尝试一把。假如明文是123,那么代入到加密公式中:

123^5 mod 221 = 106

所以106就是密文。将密文代入到解密公式中,如下:

106^29 mod 221 = 123

解出密文为123

完美!完美!简直完美!比老王的meshbox还完美

TIPS:如何计算106的29次方。由于结果太大,很多计算器一般都是直接GG。所以,可以化解一下106的29次方:

106^29 = 106^(6+6+6+6+5) = (106^6)*(106^6)*(106^6)*(106^6)*(106^5)

取余的时候:

( (106^6) mod 221 ) * ( (106^6) mod 221 ) * ( (106^6) mod 221 ) * ( (106^6) mod 221 ) * ( (106^5) mod 221 ) mod 221

以上就是RSA数学理论推演过程,上面这些数学因素是如何在程序里得到体现的呢?

代码语言:javascript
复制
<?php// 产生一个一对新的RSA公私钥$res = openssl_pkey_new();// 该函数获取一下私钥openssl_pkey_export( $res, $private_key, "123456" );// 该函数获取公钥$public_key = openssl_pkey_get_details( $res );echo PHP_EOL;echo $private_key;echo PHP_EOL.PHP_EOL;echo $public_key['key'].PHP_EOL.PHP_EOL;// 打印相关信息$n = bin2hex( $public_key['rsa']['n'] );$n = gmp_init( $n, 16 );  $n = gmp_strval( $n, 10 );echo 'n:'.$n.PHP_EOL.PHP_EOL;$e = bin2hex( $public_key['rsa']['e'] );$e = gmp_init( $e, 16 );  $e = gmp_strval( $e, 10 );echo 'e:'.$e.PHP_EOL.PHP_EOL;$d = bin2hex( $public_key['rsa']['d'] );$d = gmp_init( $d, 16 );  $d = gmp_strval( $d, 10 );echo 'd:'.$d.PHP_EOL.PHP_EOL;$p = bin2hex( $public_key['rsa']['p'] );$p = gmp_init( $p, 16 );  $p = gmp_strval( $p, 10 );echo 'p:'.$p.PHP_EOL.PHP_EOL;$q = bin2hex( $public_key['rsa']['q'] );$q = gmp_init( $q, 16 );  $q = gmp_strval( $q, 10 );echo 'q:'.$q.PHP_EOL.PHP_EOL;

上面代码保存运行一下,至于你们那里能不能运行,反正我这里能运行:

代码解析:我们知道,一般使用RSA的时候都需要什么私钥pem文件之类的,实际上就是一坨base64文本,实际上通过PHP的openssl函数可以直接生成一对RSA公私钥,也就是代码中openssl_pkey_new函数,然后我们可以直接将私钥和公钥内容可以直接打印出来。那么,我们在数学理论中那一大坨p、q、e、d、n这些数值是如何体现的呢?这些全都保存在上述演示代码的public_key数组中去了,但是,由于p、q等这些数值可能会非常非常巨大,所以,必须要使用gmp进行转换后才能显示。

私钥pem文件中的那坨base64就是按照一定的规则和方式将p、q、e等这些数值进行编码排序后最后进行一次base64编码,所以,你知道了私钥pem文件中的内容就可以根据相反的规则解析出相应的p、q、e等数字,然后开始进行RSA的解密了~

具体使用RSA进行加解密的demo代码,这一系列文章写到这个份上,演示demo代码我就不用写了吧。文章写到这里(加解密系列的第四篇)这种代码你自己查查php手册就是可以搞定了的,github上也有大量的库可以直接薅下来用。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 高性能API社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档