vlambda博客
学习文章列表

说一说对称和非对称加密

加解密早在计算机没出现之前就已经存在了,并且加解密在计算机领域也普遍使用。为什么要有加解密,因为在互联网通信中,明文传输不安全,可能会被坏人利用从而导致问题。

现代计算机系统将加密分为对称加密和非对称加密。

对称加密(Symmetric Cryptography)

 

对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。

 

对称加密通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率,是一个trade-off。

 

在实际工程项目中,给业务分配appid+appkey的方式,让业务在请求时带上appid和signature,signature的生成方式使用sha245(appkey+random+timestamp),然后业务请求header带上appid、random、timestamp和signature,服务端收到之后,获取header里的appid、random、timestamp。并根据appid查到appkey,按照同样的方法生成signature2,并对比signature和signture2相等性。整个过程不是明文传输appkey。

加密过程:

 

func GetSignature(appkey, random, timestamp stringstring {

 

    artStr := appkey + random + timestamp

    h := sha256.New()

    h.Write([]byte(artStr))

 

    return hex.EncodeToString(h.Sum(nil))

}

客户端生成signature以及服务端验证signature的过程就是对称加解密的过程。

 

非对称加密:

我们再来说说非对称加密,非对称加密是一种比对称加密更加优秀的加密算法,当然算法有利有弊,对称加密速度快但是安全性相对于非对称加密来说低,为什么呢,你想啊,要想使用对称加密,那么分享信息的各个个体之间都需要分享这个密钥,比如你们1000个人之间都使用同一个密钥进行密文传输,只要其中一个人密钥被盗窃了,那么整体加密的信息将都被破解了。好了,那么我们开始说说非对称加密。

 

就从上面提到的这个对称加密的缺点开始,怎么做到即时一个人的密钥被盗窃了,最起码保证你给其他人发送密文不被破解。于是,人们就想出了这么个办法,首先,我们停止分享共同的密钥,因为上面的bug就是来源于共享一个密钥,那么怎么办呢?每个人生成一个“私钥-公钥”对,这个私钥需要每个人自行进行保护!公钥可以随便分享,后面详细说,同时,生成的这个“私钥-公钥”对还有个强大的功能就是,使用私钥加密的信息,只能由该私钥对应的公钥才能解密,使用公钥加密的信息,只能由该公钥对应的私钥才能解密!

非对称加密应用场景也非常普遍,例如ssh、HTTPS、TLS等都是使用非对称加密

这里举一个例子:

 

一个数学小魔术:让对方任意想一个3位数,并把这个数和91相乘,然后告诉我积的最后三位数,我就可以猜出对方想的是什么数字啦!比如对方想的是123,那么对方就计算出123 * 91等于11193,并把结果的末三位193告诉我。看起来,这么做似乎损失了不少信息,让我没法反推出原来的数。不过,我仍然有办法:只需要把对方告诉我的结果再乘以11,乘积的末三位就是对方刚开始想的数了。可以验证一下,193 * 11 = 2123,末三位正是对方所想的秘密数字!其实道理很简单,91乘以11等于1001,而任何一个三位数乘以1001后,末三位显然都不变(例如123乘以1001就等于123123)。知道原理后,我们可以构造一个定义域和值域更大的加密解密系统。比方说,任意一个数乘以400000001后,末8位都不变,而400000001= 19801 * 20201,于是你来乘以19801,我来乘以20201,又一个加密解密不对称的系统就构造好了。甚至可以构造得更大一些:4000000000000000000000000000001= 1199481995446957 * 3334772856269093,这样我们就成功构造了一个30位的加密系统。这是一件非常cool的事情,任何人都可以按照我公布的方法加密一个数,但是只有我才知道怎么把所得的密文变回去。其安全性就建立在算乘积非常容易,但是要把4000000000000000000000000000001分解成后面两个数相乘,在没有计算机的时代几乎不可能成功!但如果仅仅按照上面的思路,如果对方知道原理,知道我要构造出带很多0的数,根据19801和8位算法这2个条件非常容易穷举出400000001这个目标值。要解决这个问题,真实世界就不是使用乘法了,比如RSA算法使用的是指数和取模运算,但本质上就是上面这套思想。