密码学知识
非对称密码学(公钥密码学)
在对称密码学中,加密和解密使用相同的密钥,加密函数和解密函数也非常类似。但对称密码方案存在一些问题
-
密钥分配问题:Alice和Bob必须使用一个安全的信道来传输密钥。也就是说在传输消息的信道上传输密钥是不安全的,通信双方需要重新建立一个安全的信道来传输密钥。
-
密钥个数:由于加密和解密使用相同的密钥,也就是说每两个人之间有一把钥匙,如果网络中有n个用户,则整个网络需要的密钥对数为
n ( n − 1 ) / 2 n(n-1)/2 n(n−1)/2 -
对通信双方的欺骗没有防御机制:通信双方加密后的消息是相同的,即我们收到一个密文,无法判断这个密文是通信双方的那一个人产生的,这就导致了通信双方有可能抵赖。
针对对称密码的这些缺点,就有了非对称密码。
在非对称密码体系中,密钥被分为了公钥和私钥两个概念。公钥就是在网络上公开的密钥,任何人都能使用这个公钥对消息进行加密;但使用公钥加密后的密文只能用与这个公钥相匹配的私钥进行解密(逆向的过程被称为数字签名。即私钥加密,公钥解密,虽然公钥是公开的,但私钥加密产生的数字签名只是为了证明这条消息是你发出的,并不会泄露其他的信息)每个人都会产生一对密钥,公钥公开用来对数据进行加密,私钥自己保留用来对密文进行解密。公钥加密的基本协议如下:
因为公钥是公开的,所以任何人都可以使用公钥伪造消息发送给别人,解决这个问题的方法是使用公钥证书(将用户身份与用户公钥绑定 公钥、私钥、数字签名、数字证书)。在这个协议中,公钥是公开的,因此可以在不安全的信道上传输密钥。公钥加密虽然在安全性和密钥分配上有一定的优势,但公钥加密的速度非常慢,许多分组密码和序列密码的加解密速度都会比公钥算法的加密速度快很多。因此实际的数据加密过程中是将对称加密与非对称加密结合起来使用的。使用对称加密对数据进行加密,然后使用公钥加密对对称加密的密钥进行加密传输,通过这种结合的方式克服原有对称加密或非对称加密的缺点。下面是使用AES对称密码的基本密钥传输协议。
几个定义的补充:
- 单向函数,函数f()是一个计算函数,仅当
y=f(x)在计算上是容易的,且x=f-1(y)在计算上不可行的
最大公约数(gcd),两个正整数的gcd可表示为gcd(r0,r1),表示被r0,r1 同时整除的最大正整数。欧几里得辗转相除法可以用来求两个整数的最大公约数。
模逆元,如果,d,e满足
d·e≡1mod(n)则称d,e关于模n互为模逆元,扩展欧几里得算法用来求模逆元。
比较主流的几种公钥算法:
- 整数分解方案 这个方案是基于因式分解大整数非常困难这一事实,即给定一个特别大的数,无法在短时间内判断这个大整数是由哪两个数相乘得到的。这个方案中的代表算法是RSA。
- 离散对数方案 不少算法都基于有限域内的离散对数问题,最典型的例子包括Differ-Hellman密钥交换。
- 椭圆曲线方案
Differ—Hellman密钥交换
Differ—Hellman密钥交换(DHKE)是由Whitfield Differ和Martin Hellman在1976年提出的,也是在公开文献中发布的第一个非对称方案。DHKE的基本思想为,Zp*内的指数运算(p是素数)是单向函数,并且该指数运算是可交换的,即
值k是一个联合密钥,可以当作通信双方的会话密钥来使用。DHKE协议由两个协议组成:握手协议和主要协议;其中主要协议负责执行真正的密钥交换。
The Diffie–Hellman Key Exchange (DHKE) is a key exchange protocol and not used for encryption
握手协议:
密钥交换过程:
通过这个过程,Alice和Bob共享了一个会话密钥KAB,这个密钥可以作为对称加密的密钥为双方之间建立一个安全的通信。
代数知识补充 群、子群、有限群、循环群
- 群
定理:集合Zp*由所有i=0,1,…,n-1整数组成,其中满足gcd(i,n)=1的元素与乘法模n操作形成了阿贝尔群,且单位元为e=1
有限群:一个群(G,o)是有限的,仅当它拥有有限个元素。群G的基或阶可表示为|G|
循环群
元素的阶:群(G,o)内某个元素a的阶ord(a)指的是满足以下条件的最小正整数k(1是G的单位元):
循环群:如果群G包含一个拥有最大阶ord(α)=|G|的元素α,则称这个群是循环群。拥有最大阶的元素称为原根(本原元)或生成元。
示例:
定理:对每个素数p,Zp*都是一个阿贝尔有限循环群。
离散对数问题
从前面介绍的群的内容可知,整数x一定存在,因为α是一个本原元,而每个群元素可以表示成任何本原元的幂值(示例8.6)。这个整数x也称为以α为基的β的离散对数,可以正式的写为:
如果参数足够大,计算离散对数模一个素数是一个非常难的问题。但指数运算非常简单,这就形成了一个单向函数。
Diffie-Hellman密钥交换的安全性
回顾前面的密钥交换过程,假设有一个坏人O,他的目的就是计算Alice和Bob之间的共享密钥KAB。O能得到的信息就是α和p(公开的),O还可以通过窃听的方式得到Alice和Bob的公钥A、B。问题就是他能否从已知的α、p、A、B计算出k=αab。这个问题也称为Diffie-Hellman问题(DHP)。较为正式的描述如下:
求解Diffie-Hellman问题的一个通用方法是:假设O知道计算计算Zp*内离散对数的有效方法,便可以通过以下两步求解DHP问题,得到密钥KAB
事实上步骤(1)是非常困难的!
DDH问题
The Decisional Diffie-Hellman Problem (DDH)
这是另一个离散对数的问题,用于证明难以区分的属性.假如说Alice和Bob执行如上所述的Diffie-Hellman密钥协议,那么G,g,ga,gb都是公共的,gab是密钥.直观上,DDH问题就是是否对手能够从随机的G中的元素区分出Alice和Bob的密钥gab.正式来说:
给定G,g,ga,gb和Tx使得T0是G中随机的一个元素,T1=gab同时x被随机均匀的从{0,1}中选择,找出x
数字签名
数字签名与手写签名具有某些相同的功能,它们都提供了一种方法,保证每个用户都可以验证消息,即该消息的确来自于声称产生该消息的人。
有如下场景:假设通信双方Alice和Bob共享了一个密钥;并且该密钥与一个分组密钥一起用于加密。当Alice接收消息并解密出一个具有语法意义(即这条消息由明确的含义)的消息,通常情况下她可以直接得出结论:该消息的确是由与自己共享私钥的人发出的。如果只有Alice和Bob知道此密钥,则他们可以确定在传输过程中没有第三方修改了此消息,而这个推断也是合情合理的。然而在实际中Alice和Bob一方面都想与对方进行安全通信,另一方面也可能对欺骗对方感兴趣。
现有的公钥加密方案保证了加密双方之间的通信是安全的,但如果有一个第三方(公证人)要判断一个消息是由Alice还是Bob发出的,就会产生问题,即Alice和Bob有可能抵赖。因为通信双方知道的关于密钥的信息相同,所以他们拥有的能力也完全相同,中立的第三方就不能分辨出某个加密操作是由Alice还是Bob或他们一起执行的。数字签名就是为了防止这种欺骗。
数字签名的基本原理
基本思想:对消息签名的一方使用私钥,接收方则使用对应的公钥。
签名算法是Bob的私钥的一个函数,因为Bob的私钥只有Bob知道,所以只有他本人可以对消息签名,得到签名s后将其附加在消息的后面一同发给Alice。
通用的数字签名协议:
最重要的安全服务包括:
- 保密性:只有被授权的人才能访问信息。
- 完整性:消息在传输过程中未被更改。
- 消息验证:消息的发送者是可信的。
- 不可否认性:消息的发送者无法否认其生成了消息。
群签名
所谓群签名(group signature)就是满足这样要求的签名:在一个群签名方案中,一个群体中的任意一个成员可以以匿名的方式代表整个群体对消息进行签名。与其他数字签名一样,群签名是可以公开验证的,而且可以只用单个群公钥来验证。
群签名有如下几个特点:只有群中成员能够代表群体签名(群特性);接收者可以用公钥验证群签名(验证简单性);接收者不能知道由群体中哪个成员所签(无条件匿名保护);发生争议时,群体中的成员或可信赖机构可以识别签名者(可追查性)。
零知识证明
零知识证明系统一般由两方可以相互交互的对手组成,其中证明者为Peggy(prover),验证者为Victor(verifier)。证明者拥有一个私有信息S,他的目的是向验证者证明他确实拥有私有信息S同时又不泄露任何关于私有信息的具体内容,而验证者要想办法验证证明者确实拥有私人信息S而不能让任何没有私有信息S的对手欺骗他而使他误认为对手拥有私有信息S。显然这个私有信息S包含的信息量不为零,也就是说这个私有信息能外在表现出一些性质,证明者和验证者都要依赖这些私有信息的性质来完成交互验证过程,一个随机生成的字符串包含信息量为零,是没有办法构造一些零知识验证系统的。
零知识证明的三个特性:
- 完备性 如果证明者确实拥有这个私有信息S,他一定可以说服验证者相信他拥有私有信息S
- 可靠性 如果证明者没有这个私有信息S,他没有办法通过欺诈的手段让验证者相信他拥有私有信息S
- 零知识性 当协议完成后验证者验证了证明者手中有私有信息S且验证者只能知道证明者确实拥有了私有信息S,验证者得不到关于私有信息S的其它信息。也就是说无论验证者怎么调整自己的验证步骤并把交互步骤和结果记录下来,他都没有办法向第三方证明他知道私信息的任何知识(其中包括原证明者拥有私有信息S这一事实本身,他都没有办法向第三方证明性的传递
哈希函数、bloom过滤器
哈希函数计算了一个消息的摘要,而这个摘要是非常短的、固定长度的位字符串。对某个特定的消息而言,消息摘要(哈希值)可以看作是该消息的指纹,即消息的唯一表示。
有了哈希函数后,数字签名就可以由原来的对消息进行签名变成对消息的哈希函数进行签名。即签名和验证都是作用于消息的哈希值。使用哈希函数进行数字签名的基本协议如下。
哈希函数有这样几个性质:
- 对任意大小的消息使用哈希函数,在计算上都是高效的
- 哈希函数的输出长度是固定的
- 哈希函数的输出值对所有输入位都是高度敏感的,即如果输入x发生了很微小转变,输出值会变得截然不同
哈希函数的安全性
为了保证安全性,哈希函数具有以下三个属性:
- 抗第一原像性或单向性
哈希函数具有单向性。给定一个输入,求这个输入值的哈希值是简单的;但如果根据这个哈希值逆向求对应的输入值在计算上是不可行的。
- 抗第二原像性或弱抗冲突性
z1=h(x1)=h(x2)=z2在计算上是不可行的,即使用相同的哈希值创建两个不同的消息在计算上是不可行的。在这种情况中,通常是给定了x1,试图寻找x2。由于每个哈希函数拥有固定长度的输出,比如n位,所以可能的输出值只有2n个,而且哈希函数对其输入值的数目没有限制,所以一定会存在多个输入哈希到相同输出值的情况。
- 抗冲突性(强抗冲突性)
第二种情况是给定了x1,而在这种情况中,攻击者可以随机选择x1,x2;找到两个不同的输入具有相同的哈希值在计算上是不可行的。显然第三种中的限定条件更弱,所以称为强抗冲突性。
布隆过滤器
布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一元素存在于某集合中,但是实际上该元素并不在集合中)和删除困难,但是没有识别错误的情形(即假反例False negatives,如果某个元素确实没有在该集合中,那么Bloom Filter 是不会报告该元素存在于集合中的,所以不会漏报)。
算法:
- 首先需要k个hash函数,每个函数可以把key散列成为1个整数
- 初始化时,需要一个长度为n比特的数组,每个比特位初始化为0
- 某个key加入集合时,用k个hash函数计算出k个散列值,并把数组中对应的比特位置为1
- 判断某个key是否在集合时,用k个hash函数计算出k个散列值,并查询数组中对应的比特位,如果所有的比特位都是1,认为在集合中。
优点
相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数。另外, Hash 函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。
布隆过滤器可以表示全集,其它任何数据结构都不能;
k 和 m 相同,使用同一组 Hash 函数的两个布隆过滤器的交并差运算可以使用位操作进行。
缺点
但是布隆过滤器的缺点和优点一样明显。误算率(False Positive)是其中之一。随着存入的元素数量增加,误算率随之增加。但是如果元素数量太少,则使用散列表足矣。
另外,一般情况下不能从布隆过滤器中删除元素. 我们很容易想到把位列阵变成整数数组,每插入一个元素相应的计数器加1, 这样删除元素时将计数器减掉就可以了。然而要保证安全的删除元素并非如此简单。首先我们必须保证删除的元素的确在布隆过滤器里面. 这一点单凭这个过滤器是无法保证的。
Counting Bloom filter
将标准Bloom Filter位数组的每一位扩展为一个小的计数器(Counter),在插入元素时给对应的k(k为哈希函数个数)个Counter的值分别加1,删除元素时给对应的k个Counter的值分别减1。Counting Bloom Filter通过多占用几倍的存储空间的代价,给Bloom Filter增加了删除操作。
https://www.cnblogs.com/the-zym/p/13217986.html