导读
这是我的第一篇博文。在我本科学到的密码学课上,密码学就给我留下了理论艰深,概念繁多的可怕阴影,秘钥长度之长,处理过程之繁琐曾让我一度怀疑自己不是一个合格的工科生。因区块链开发中再次涉及到了密码学的相关知识,所以这几天又系统的学习了一遍,本文是一些对密码学的知识的整理。首先,我会对密码学学科的概念及背景进行简单介绍。其次,我会通过具体案例来说明密码学的安全原理。最后,我对现在不同的加密算法库及其应用场景进行了分类整理,方面大家对照选取。
本文的主要参考博客如下:
《现代密码学指南》https://blog.helong.info/blog/2015/06/06/modern-crypto/
《Node.js区块链开发》https://blog.csdn.net/shebao3333/article/details/79538354
一.为什么需要密码学?
就如人穿衣是为了保证个体隐私性一样,在复杂的互联网上传输的数据同样需要隐私性。密码学作为一门研究如何隐秘的传输信息的学科,是为互联网中传输数据穿衣加盾的最好工具。
二.密码学如何保证信息安全?
著名密码学家Colin Percival 在其公开演讲Everything you need to know about cryptography in 1 hour中曾指出,密码学被攻破常常是因为编写者使用错误的工具或者以错误的方式使用它们,经验告诉我们不要尝试亲自写密码学代码,因为那往往都是有漏洞的。
密码学中主要研究三个对象:
1.明文(plaintext):我们想要保护的原始数据
2.密文(ciphertext):经过密码学加密处理后的数据,这部分数据往往会被攻击者得到
3.秘钥(secret key):是明文密文相互转化的工具
下面我会以《Node.js区块链开发》中的一个小例子,来具体说明密码学是如何保证数据在互联网中的安全传输的。
安全需求:
一个男生Bob想要和自己心仪的女生Alice表白,说出“I LOVE YOU”。但是Bob很腼腆不敢当面表达自己的心声,因此他就想到将这句话使用信息加密的方式传输给他,让女生Alice使用密码进行解密,搞一波摩尔斯电码的浪漫。为了保证男生可以以这种方式表白成功,他需要考虑以下四个问题:
(1)加密:信息只能女生Alice看见,其他人不可以看见
(2)解密:女生Alice在收到加密后的信息后,可以成功解密得到男生的心声“I LOVE YOU”
(3)签名:男生Bob为信息签名,保证信息在传递的过程中不被修改,类似于我们日常生活中的笔迹签名
(4)验证:女生收到信息后根据签名的签名可以确定信息确实为男生所传递
解决步骤:
(1)生成密钥对(密码是打开密码箱的唯一方式)
//加载工具模块,crypto用来加密解密信息, ed25519用来签名验证信息
1 var crypto=require("crypto"); 2 var ed25519=require("ed25519");
//选取密码,生成对应信息摘要,继而生成相应的公私钥对 BobKeyPair(publickey,privatekey)
1 var password="123456"; //密码 2 var hash=crypto.createHash("sha256").update(plaintext).digest(); //明文摘要 3 var BobKeyPair=ed25519.MakeKeypair(hash); //为了使得心仪女生Alice知道心意,Bob将BobKeyPair.publicKey传给Alice
(2)Bob加密信息
//使用公钥 BobKeyPair.publicKey 进行加密
1 var plaintext="Alice,I Love you!"; //明文 2 var msgCiphered=cipher("aes192",BobKeyPair.publicKey,plaintext); //密文
(3)Bob给信息签名
//使用私钥 BobKeyPair.privateKey 进行签名
1 var Bobsig=ed25519.Sign(new Buffer(msgCiphered,"utf-8"),BobKeyPair.privateKey);
(4)Alice验证并解密加密后的信息(msgCiphered,Bobsig)
//为了安全起见,一般都是先验证安全性,再去解密信息,这符合我们的常识
//使用Bob之前提供的公钥进行签名认证,确认信息的发送者确实是Bob则进行解密操作,否则返回错误信息
1 if(ed25519.Verify(new Buffer(msgCiphered,"utf-8"),BobSig,BobKeyPair.publicKey)){ 2 console.log("签名合法,确实是Bob发来的信息!"); 3 var Desmsg=decipher("aes192",BobKeyPair.publicKey msgCiphered); 4 console.log("Bob said:"+Desmsg); 5 ) else{ 6 console.log("对方不是Bob,要小心"); 7 }
经过一系列的操作,Bob终于表达了自己的想法,且保证没有被其他人发现自己的心思。希望以上的小故事能让你对密码学的加解密过程有一个大致的了解,对密码学的探索欲望也强了一点。
三.不同情境下如何选择相应的加密算法?
上一节密码学如何保证信息安全中有提到,秘钥(secret key)是明文与密文成功转换的关键所在。因此就有了著名的对称加密和非对称加密两种算法。接下来我会从不同的方面分别给出对应的选择策略
对称加密:加密和解密的秘钥key至始至终使用的是同一个
非对称加密:加密和解密相互转换时使用的秘钥不同,一个叫公钥一个叫私钥
1.数据加密算法选择(ECC>RSA)
(1)NaCl库/libsodium库中的crypto_secretbox()/crypto_secretbox_open() 函数》》》》》》》》(2)Chacha20-Poly1305 算法》》》》》》》》》(3)AES-GCM 算法
三者按优先级排序推荐使用,具体区别请查看《现代密码学实践指南》
2.秘钥长度选择(推荐256bit)
下表对比了相同安全程度时,不同算法的密钥长度,单位:bit
3.签名算法选择
对称加密:HMAC类算法(择SHA2类的算法:: SHA-256, SHA-384, SHA-512, SHA-512/256)
SHA2类算法的区别于介绍可见:https://en.wikipedia.org/wiki/SHA-2
非对称加密:NaCl,Ed25519
4.随机ID生成(推荐256bit)
一定要使用 /dev/urandom
避免用户空间的随机数生成器如:havaged,prngs,egd,等
5.客户端-服务器结构层的传输协议选择(TLS)
6.网站(支持https协议)选择
OpenSSL,Google的BoringSSL,或者是 AWS的 ELB 都是不错的选择
后记
以上是在学习的过程中的一点积累和认识,因非专业密码学专业出身里面难免会有不清楚的地方,希望以后可以再接再厉!!
原文地址:https://www.cnblogs.com/dxtlearningblockchain/p/10776780.html