区块链学习第一月作业 - 到底什么是RSA加密

原文 在此
本来RSA跟区块链并无联系, 但是非对称加密以及私钥/公钥的理解相似, 因此理解RSA对与理解ECC有相当大的帮助, 因此这里再炒一次剩饭.

RSA加密演算法是一种非对称加密演算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

上面是维基百科对RSA加密算法的定义, 具体内容请点此(wikiwand让你以更优雅的姿势查看维基百科)查看.

最近在学习区块链知识, 读了<<精通比特币>>, 想把椭圆加密算法搞懂, 但是感觉很懵B, 想着先把RSA搞懂了, 再去啃硬骨头.

我们以经典的 Alice 和 Bob 举例

原始方法: 明文

Bob 是一个才子, Alice 是个美人. Bob 喜欢 Alice, 经常给 Alice 写纸条. 慢慢的 Alice 也开始给 Bob 回复纸条.
这是最原始的通信方式: 你说什么我收到什么.

双向加密

后来, Bob 和 Alice 关系有了一些进展, 班里开始有一些八卦, 传递纸条的同学忍不住开始偷窥内容. Alice 开始不再回复 Bob 的纸条, 也不太高兴, 不想让 Bob 给她传纸条了.
Bob 是个才子, 想出来一个方法: 约定一个密码, 把想写的字换掉, 比如密码是一本<<三国演义>>, 三字在第十页第二行第三字, 便写作 0100203, 国字在第200夜第10行第20字, 变成2001020. Bob 教会了 Alice 这个方法. 这样他们俩就又能开开心心地传纸条了.

双向加密的不安全性

好景不长, Alice 有一次在回复纸条时被归蜜 Lucy 撞见, Lucy 是个大嘴巴, 这样班里人手一本<<三国演义>> 大家都开始了这种时髦的通信方式, 一时间语文老师开心的不行, 以为大家突然开窍了.

RSA

Bob 想让 Alice 换一本书把, Alice 觉得太麻烦而且大家都知道怎么玩的了再要隐密传递也不太可能. 所以 Bob 回家苦心钻研, 终于发现了一个神奇的方法: RSA. (其实RSA由三人共同设计)

圆不回来了, 正题开始

公钥与私钥的产生

RSA 加密算法的核心在于一对密钥与公钥, 那么怎么产生自己的密钥和公钥呢?

  1. 随机选择两个不相等的质数p和q
  2. 计算p和q的乘积n
  3. 计算n的欧拉函数φ(n)
  4. 随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质
  5. 计算e对于φ(n)的模反元素d
  6. 将n和e封装成公钥,n和d封装成私钥

"Talk is easy, show me the code."
通过示例看一下具体过程:

var BigNumber = require('bignumber.js'); // js 处理数字的位数有限, 避免溢出

// 随机选择两个数字
var p = 47;
var q = 97;

var N = p * q;
var r = (p - 1) * (q - 1);

// console.log(N, r); // 4559 4416

var e = 5; // 1 < e < r && e r 互质
// 计算e对于r的模反元素d。
var d;
// e * d % r = 1; // 模反元素
// 上面的算式 等价于: e * d + k * r = 1
// 已知 e = 3; r = 4416; 5 * d + k * 4416 = 1; // "扩展欧几里得算法" 可以求解, 至于具体的数学方法, 我不太懂. 使用下面的简单方法也可求解.
// for (var i = 10; i > -100; i--) {
//   var result = (1 + i * 4416) / 5;
//   console.log(i, result);
//   if (result.toString().indexOf('.') < 0) {
//     break
//   }
// } 
// 使用上面的代码得出其中一个解为: 7949, -9;
d = 7949;

// 得到公钥/私钥, 其中任意一组作为公钥都可以, 另一组作为私钥自己保存
// PrivateKey: (4559, 5)
// PublicKey:  (4559, 7949)

加密过程

function rsa(key1, key2, message) {
  message = +message;
  if (key1 < 1 || key2 < 1) {
    return 0;
  }
  //加密或者解密之后的数据
  var rsaMessage = 0;

  //加密核心算法
  rsaMessage = (new BigNumber(message)).toPower(key2).modulo(new BigNumber(key1));
  return rsaMessage.valueOf();
}

function test(msg) {
  var encodeMsg = rsa(N, e, msg);
  var decodeMsg = rsa(N, d, encodeMsg);
  console.log('原始数据: ', msg, ', 密文: ', encodeMsg, ': 解密: ', decodeMsg);
}
test();

运行node index.js, 产生以下输出:

原始数据:  10 , 密文:  4261 : 解密:  10
原始数据:  20 , 密文:  4141 : 解密:  20
原始数据:  30 , 密文:  530 : 解密:  30
原始数据:  40 , 密文:  301 : 解密:  40
原始数据:  50 , 密文:  3345 : 解密:  50
原始数据:  60 , 密文:  3283 : 解密:  60
原始数据:  70 , 密文:  1855 : 解密:  70
原始数据:  80 , 密文:  514 : 解密:  80
原始数据:  90 , 密文:  1138 : 解密:  90

信任问题

上面的方法是没问题了, Bob 使用 Alice 的公钥 加密自己的消息, Alice 收到之后, 使用自己的消息解密, 但是这个方式没有办法确认消息来源, 如果 Jim 也使用这个方式来加密消息传给 Alice, 那么 Alice 怎么确认消息�的真实性呢?

是的, 聪明如你一定想到了, 签名啊, Bob使用自己的私钥来对发送的消息签名, 这样别人即使知道如何加密解密, 但是无法知道 Bob 的私钥, 是无法冒充的 Bob 的. 看一下具体过程:
上面有了 Alice 的私钥/公钥对, 我们可以用同样的方式给 Bob 找到一对私钥/公钥, 假设是(33, 3) 和 (33, 7)

  1. 比如 Bob 想要发送消息 14 给 Alice
  2. 使用 HASH 方法计算出消息的 HASH 值为 4,
  3. 使用 Bob 自己的私钥(33, 3)对 HASH 签名 为 31
  4. 那么消息变成了 1431, Bob 再次使用 Alice 的公钥加密此消息(882)传递给 Alice
  5. Alice 收到消息之后, 使用自己的私钥解密得到1431
  6. 我们已经知道这是一个包含签名的消息, 后两位是签名(真实情况, 签名比这个复杂, 但是原理相似), Alice 首先得到消息内容 14, 然后开始校验签名 31, 之前我们知道 RSA 是不可逆单向加密, 那么如何校验签名呢?
  7. Alice 其实不需要知道这个消息是谁发送的, 只需要知道它是不是来自 Bob 就行, 因此她使用 Bob 的公钥对此签名解密, 得到 原始消息 Hash 4, 然后使用和 Bob 相同的一套 Hash 算法, 计算消息 14 的 Hash 也是 4, Alice 很开心, 她知道这是 Bob 在向她表达一世.

这一过程简单代码示意如下:

var message = 14;
var hashOfMessage = hash(message);
var signature = rsa(33, 3, hashOfMessage);

var hashMessage = +`${message}${signature}`;
console.log('原始消息: ', message, 'Hash: ', hashOfMessage, 'Hash 签名', signature, '签名消息', hashMessage);

var encodeMsg = rsa(N, e, hashMessage);
console.log('收到消息: ', encodeMsg);

var decodeMsg = rsa(N, d, encodeMsg);
console.log('解密消息: ', decodeMsg);
// 最后2位是签名
var sentMsg = +(decodeMsg.toString()).slice(0, 2);
var sentHash = +(decodeMsg.toString()).slice(2);
console.log('原始消息:', sentMsg, '签名:', sentHash);
var rightHash = hash(sentMsg);
var decodeHash = rsa(33, 7, sentHash);
console.log('正确签名: ', rightHash, '校验签名: ', decodeHash);

安全性

上面的例子中选取的密钥都是简单密钥, 很容易被破解, 而且通过代码我们可以知道, 公钥/私钥第一位数字是加密算法一次处理上限, 大于该值加密无效.
但实际应用中我们会选择比较大的数字 作为 公钥/私钥组合, 这样破解难度也将高到极致.
比如数字: 1230186684530117755130494958384962720772853569595334792197322452151726400507263657518745202199786469389956474942774063845925192557326303453731548268507917026122142913461670429214311602221240479274737794080665351419597459856902143413, 你知道哪两个数相乘等于它吗? 参考链接里面可以看到答案.

关于 RSA 就先写到这儿.

参考

  1. 维基百科 RSA 词条
  2. RSA算法原理(一)
  3. RSA算法原理(二)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容