返回介绍

三张图让你全面掌握加密解密技术

发布于 2025-02-22 21:56:41 字数 4995 浏览 0 评论 0 收藏 0

前言

加密解密技术,涉及面很广,这里,把前人的研究成果汇总起来,通过图表的形式来帮助记忆和筛选,方便日后使用。内容主要包括两个方面,一个是场景与算法,一个是 Node.js 的相关模块或组件。共三张脑图,具体请看:

1.加密解密纵览

下面这张图,是在 《密码学一小时必知》(见参考)基础上完成的,原作者是 Colin Percival,密码学方面的专家,FreeBSD 项目的安全长官,Tarsnap 在线备份服务的创始人,scrypt 密钥衍生算法的作者,非常值得参考学习。译者是 @byronhe ,翻译贡献这样的好文,包括下面有关论述场景与算法的实践指南,值得去为他点赞。

这张图,可以告诉你密码学中的概念,目的,案例,以及最佳的实践经验。

加密解密.png

2.场景与算法

这张图,是基于 《现代密码学实践指南(2015 年)》(见参考) 完成的。可以说,在上一张图的基础上,更加具体,特别是对于场景的描述,让码农可以更加方便的作出正确的选择,值得拥有。其中,标注序号的,是有优先级的。

场景与算法选择.png

3.Node.js 中的的加密和解密、签名与认证

这张图,主要参考了官方文档及其他一些文档(见参考),按照我个人的理解画得。如果你使用 Node.js,基本上拿来看看图解,就能直接用了。特别是,默认选择了 ed255519 组件,如果你看了上面两篇实践,就知道这是签名与认证最好的选择,因此这里可以肯定的说,Crypto 模块的签名与认证还是暂时不要用吧。 Ebookcoin 就是这么实践的,上一篇源码介绍的很详细。另一个是 Natrium 组件,也可以用于签名和认证,但主要是用来非对称加密和解密的。这张脑图里的三个组合,按照上面的实践经验来说,应该是当前 Node.js 加解密应用领域的最佳组合方案。

Node.js 中的的加密和解密、签名与认证

4.趣味实践

还是用在《 在 Node.js 中使用加密解密技术 》里的的例子吧。设定角色,男生叫做 Bob,他的女友叫 Alice。

场景

Bob 想向女友表达埋藏已久的心声“I love you!”,但碍于男人的颜面(男人都这样吗?),不好意思当面说出口,只好加密传输。这里基于一个可行的假设,就是他们已经拥有彼此的公钥,或者可以简单获得。

需求

  • 加密:不能让别人看到信息;
  • 解密:女友可以恢复并查看;
  • 签名:Bob 可以签名信息,确保不被篡改;
  • 认证:女友收到信息,可以验明正身,确认是 Bob 所发,而不是别人的恶作剧。

方案

利用以上三张图,我们可以很快拿出技术方案。

  • 加密与解密技术:第二张图显示说,这种加密之后又解密原文的场景非常少见。技术上,最好使用 NaCl,其次是 libsodium(背后仍然是 NaCl),但是搜索了一下 github,Node.js 社区还没有相关 NaCl 稳定的封装包,libsodium 倒是有一个 Natrium(但是,写作本文时,连安装都没有成功,有验证成功的,请告诉我一声)。因此,只能选择使用 Crypto 简单加密和解密。
  • 签名与验证技术:当然最好的选择是 ed25519 了。

编码

新建一个简单的 Node.js 工程, 代码在这里: https://github.com/imfly/node.js-practice/blob/master/crypto/index.js

(1) 生成密钥对

Bob 没有使用随机字符串,而是使用一个密码,并采取 SHA256 算法生成密钥对,请看思维导图,有关 hash 的部分。

var crypto = require('crypto');
var ed25519 = require('ed25519');

var bobsPassword = 'This is my password, you don`t guess it!';
var hash = crypto.createHash('sha256').update(bobsPassword).digest();
var bobKeypair = ed25519.MakeKeypair(hash);

(2) 给信息加密和签名

通常是先加密后签名。

这里使用 Crypto 给信息进行了简单加密,把 Bob 的公钥作为加密键值(但是既然是公钥,谁会不知道呢,除非 Bob 只把公钥给了 Alice),可能还得 Bob 告诉 Alice 使用什么算法来解密。

var message = 'Hi Alice, I love you!';
var msgCiphered = cipher('aes192', bobKeypair.publicKey, message); //公钥进行加密,如果是 Natrium,这里就是私钥加密
var signature = ed25519.Sign(new Buffer(msgCiphered, 'utf8'), bobKeypair.privateKey); //私钥进行签名

(3) 给 Alice 发送签名信息

这个就各显神通了。

(4)Alice 验证并解密

通常是先验证后解密。

作为 Bob 的好朋友,Alice 有他的公钥。

if (ed25519.Verify(new Buffer(msgCiphered, 'utf8'), signature, bobKeypair.publicKey)) {
    // 验证函数返回了 true,通过验证
  var msg = decipher('aes192', bobKeypair.publicKey, msgCiphered);  //使用 Bob 的公钥解密

    console.log('签名合法,信息来自 Bob!');
  console.log('Bob said: ', msg); //显示信息
} else {
    // 验证函数返回了 false,肯定不是 Bob 的信息.
    console.log('签名不合法!');
}

(5) 补充代码

上面用到的 Crypto 的加密解密方法:

//解密
function (algorithm, key, buffer){
    var encrypted = "";
    var cip = crypto.createCipher(algorithm, key);
    encrypted += cip.update(buffer, 'utf8', 'hex');
    encrypted += cip.final('hex');
    return encrypted;
}

//解密
function decipher(algorithm, key, encrypted){
    var decrypted = "";
    var decipher = crypto.createDecipher(algorithm, key);
    decrypted += decipher.update(encrypted, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

(6) 运行实例

使用下面的命令,可以运行上述代码:

$ git clone https://github.com/imfly/node.js-practice
$ cd node.js-practice
$ npm install
$ node crypto/

输出结果:

签名合法,信息来自 Bob!
Bob said:  Hi Alice, I love you!

参考

Ed25519 第三方组件

Ed25519 官方网站

现代密码学实践指南(2015 年)

密码学一小时必知

浅谈 node.js 中的 Crypto 模块

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文