Upload
earlene-marnell
View
213
Download
0
Embed Size (px)
DESCRIPTION
网络与信息安全 密码学基础(二). 潘爱民,北京大学计算机研究所 [email protected] http://www.icst.pku.edu.cn/InfoSecCourse. 内容. 公钥算法 背包思想 RSA Elliptic curve Diffie-Hellman 密钥交换 消息算法 散列算法 数字签名 加密库 Crypto++. 公钥密码学的历史. 76年 Diffie 和 Hellman 发表了“密码学的新方向”,奠定了公钥密码学的基础 公钥技术是二十世纪最伟大的思想之一 改变了密钥分发的方式 - PowerPoint PPT Presentation
Citation preview
网络与信息安全网络与信息安全密码学基础密码学基础 (( 二二 ))
潘爱民,北京大学计算机研究所[email protected]
http://www.icst.pku.edu.cn/InfoSecCourse
内容内容 公钥算法
背包思想 RSA Elliptic curve Diffie-Hellman 密钥交换
消息算法 散列算法 数字签名 加密库 Crypto++
公钥密码学的历史公钥密码学的历史 76年 Diffie和 Hellman 发表了“密码学
的新方向”,奠定了公钥密码学的基础 公钥技术是二十世纪最伟大的思想之一
改变了密钥分发的方式 可以广泛用于数字签名和身份认证服务
78 年, RSA 算法 PKI
公钥算法应用:保密公钥算法应用:保密
公钥算法应用:认证公钥算法应用:认证
基本思想和要求基本思想和要求 涉及到各方:发送方、接收方、攻击者 涉及到数据:公钥、私钥、明文、密文 公钥算法的条件:
产生一对密钥是计算可行的 已知公钥和明文,产生密文是计算可行的 接收方利用私钥来解密密文是计算可行的 对于攻击者,利用公钥来推断私钥是计算不可行的 已知公钥和密文,恢复明文是计算不可行的 ( 可选 ) 加密和解密的顺序可交换
如何设计一个公钥算法如何设计一个公钥算法 公钥和私钥必须相关,而且从公钥到私钥
不可推断 必须要找到一个难题,从一个方向走是容易
的,从另一个方向走是困难的 如何把这个难题跟加解密结合起来
计算可行和不可行的界
公钥密码学的研究情况公钥密码学的研究情况 与计算复杂性理论密切相关 计算复杂性理论可以提供指导
但是需求不尽相同 计算复杂性通常针对一个孤立的问题进行研究 而公钥密码学往往需要考虑一些相关的问题
比如,密码分析还需要考虑已知明文、选择明文等相关的情形
讨论的情形不同 计算复杂性考虑最坏的情形 而对于公钥密码学则是不够的
一个困难问题必然会导致一个保密性很好的密码系统吗? 不一定,还需要有好的构造
背包背包 ((knapsack)knapsack) 问题问题 0-1 背包问题:
给定一个正整数 S 和一个背包向量 A=(a1,…,an) ,其中 ai 是正整数,求满足方程S = ∑aixi 的二进制向量 X=(x1,…,xn)。
这是一个 NP 完全问题,解决这个问题所需要的时间与 n 呈指数增长
背包问题用于公钥密码学 做法方法:明文为 X, S 为密文 奥妙在于有两类背包,一类可以在线性时间内求解,
另一类则不能 把易解的背包问题修改成难解的背包问题
公开密钥使用难解的背包问题 私钥使用易解的背包问题
易解的背包问题——超递增背包易解的背包问题——超递增背包 满足下列条件的背包
ai > ∑aj (j = 1,…,i-1)
这样的背包也被称为简单背包 求解
从最大的 ai 开始,如果 S 大于这个数,则减去 ai, 记xi 为 1 ,否则记 xi 为 0
如此下去,直到最小的 ai
例如背包序列 {2, 3, 6, 13, 27, 52} 求解 70 的背包
结果为 {2, 3, 13, 52} 所以,密文 70 对应的明文为 110101
转换背包转换背包 简单背包用作私钥 如何产生相应的公钥——转换
做法:选择一个整数 m > ∑ai (i = 1,…,n)
然后选择一个与 m 互素的整数 w ,然后ai’ = wai (mod m) (i = 1,…,n)
这里的 ai’ 是伪随机分布的这样得到的背包是非超递增背包
基于背包问题的公钥密码系统基于背包问题的公钥密码系统———— MHMH 公钥算法公钥算法
加密 将明文分为长度为 n 的块 X=(x1,…,xn) 然后用公钥 A’ = (a1’, …, an’) ,将明文变为密文 S
S = E(X) = ∑ai’xi
解密 先计算 S’ = w-1S mod m 再求解简单背包问题
S’ = ∑aixi
背包密码系统的意义背包密码系统的意义 是第一个公钥密码系统 有较好的理论价值 在实践过程中,大多数的背包方案都已被破解,或者证明存在缺陷
RSARSA 算法算法 1977 年由 Ron Rivest、 Adi Shamir和
Len Adleman 发明, 1978 年公布 是一种块加密算法。
明文和密文在 0~n-1 之间 ,n 是一个正整数 应用最广泛的公钥密码算法 只在美国申请专利,且已于 2000 年 9月
到期
RSARSA 算法描述算法描述 分组大小为 k, 2k < n 2k+1
加密 : C = Me mod n 解密 : M = Cd mod n = Med mod n 公钥 : KU={e,n}, 私钥 : KR={d,n} 上述算法需要满足以下条件 :
能够找到 e,d,n, 使得Med mod n = M, 对所有M<n
计算 Me和 Cd 相对容易 从 e和 n得到 d 是在计算上不可行的
RSARSA 密钥生成原理密钥生成原理 令 n=pq, pq都是素数 ,(n)=(p-1)(q-1)是 n的 Euler 数
Euler 定理推论 : 若 n=pq, pq都是素数 , k 是任意整数 , 则 mk(p-1)(q-1)+1 m mod n, 对任意 0mn
只要选择 e,d, 满足 ed=k(n)+1,即ed 1 mod (n) d e-1 mod
(n) 公钥 : KU={e,n}, 私钥 : KR={d,n}
数论基础数论基础 Fermat 定理 : p 素数 ,a 是整数且不能被 p 整除 ,则 : ap-1 1 mod p( 证明略 )
Euler 数 (n) 定义为小于 n 且与 n 互素的正整数个数 p 是素数 ,(p)=p-1 若 n 的因子分解为 n=Pi
ai, ai>0,Pi互不相同 , 则 (n)= Pi
ai(1-1/Pi) 若 gcd(m,n)=1, 则 (mn)=(m)(n), 特别地 , 若 pq 且都是素数 , (pq)=(p-1)(q-1)
数论基础数论基础 ((续续 ))
Euler 定理 : 若 a 与 n 为互素的正整数 , 则
a(n) 1 mod n
推论 : 若 n=pq, pq 都是素数 , k 是任意整数 ,则
mk(p-1)(q-1)+1 m mod n, 对任意 0mn
RSARSA 密钥生成与使用密钥生成与使用 产生密钥对
选择两个大素数 p,q, pq 计算 n=pq,(n)=(p-1)(q-1) 选择整数 e, 使得 gcd(e,(n))=1 计算 d e-1 mod (n)
公钥 : KU={e,n}, 私钥 : KR={d,n} 使用
加密 : C = Me mod n 解密 : M = Cd mod n
计算乘幂计算乘幂 计算 d=am, m=bkbk-1…b0( 二进制表示 )
d1
for ik downto 0
do d(dd) mod n
if bi = 1
then d(da) mod n
return d
原理:M = ((((((bk2+bk-1)2+bk-2)2+bk-3)2+…)2+b0
RSARSA 密钥产生密钥产生 产生两个素数
由于 n = pq 是公开的,所以,为了防止攻击者利用 n获得 p和 q ,必须选择足够大的素数 p和 q
大素数产生算法 选择 e或者 d ,然后求出另一个
大素数产生大素数产生 素数生成过程 :
随机选择一个奇数 n( 如通过伪随机数发生器)
随机选择 a, 使 a<n
进行素性测试 ( 例如用 Miller-Rabin 算法 ),若 n没有通过测试 ,抛弃 n, 转到
如果通过了足够次数的测试 , 认为 n 是素数 ,否则转到 .
素数理论 : 在 N附近,每 ln(N) 个整数中有一个素数
素性测试素性测试 Miller-Rabin 算法:用来测试一个整数是否是素数 WITNESS(a,n)
设 bkbk-1…b0 是 (n-1) 的二进制表示 d1
for ik downto 0
do xd
d(dd) mod n
if (d=1 & x1 & xn-1) return TRUE
if (bi=1) then d(da) mod n
if (d1) return TRUE
else return FALSE
如果 n 不是素数,则返回 FALSE 的概率 (即失败概率 ) 小于0.5
如返回 TRUE ,说明 n 不是素数。 不满足 an-1=a mod n 对于 x2=1 mod n ,除了 1和 n-1 之外,还有别的解
扩展扩展 EuclidEuclid 算法算法 ExtEclid(d,f): 求最大公约数或模逆 , 假定 df
(X1,X2,X3)(1,0,f), (Y1,Y2,Y3)(0,1,d)
if Y3 = 0 then return X3, no inverse
if Y3 = 1 then return 1, inverse is Y2
Q (X3/Y3) 的整数部分 (X1,X2,X3)(X1-QY1, X2-QY2, X3-QY3)
(X1,X2,X3) (Y1,Y2,Y3)
goto fX1+dX2=X3, fY1+dY2=Y3 若 Y3=1, 则 fY1+dY2=1 dY2=(-Y1)f+1
dY2 1 mod f Y2 = d-1 mod f
RSARSA 安全性安全性 基于数学的攻击
公钥 : KU={e,n}, 私钥 : KR={d,n}, n=pq 分解 n=pq (n)=(p-1)(q-1) d=e-1 mod (n) 不求出 p,q, 直接求 (n) d=e-1 mod (n) 不求出 (n), 直接计算 d
结论 已知的方法至少跟因子分解一样难度 尚未发现多项式时间的因子分解算法 因子分解的算法已经取得了长足进步
措施 : 选择足够大的 n(1024位以上 ),并且使得e,d 之间相差不太大 , 也不太小
RSARSA 其他攻击其他攻击 同模攻击
两对密钥的模 n 相同
时间攻击 利用 CPU处理某些特殊的模乘比较慢的规律
来确定每一位指数
原根原根 ((primitive root)primitive root) Euler 定理表明 , 对两个互素的整数 a,n,
a(n) 1 mod n 定义:存在最小正整数 m(n) (m|(n)), 使得am 1 mod n
若对某个 a,m=(n), 则称 a是 n 的一个原根
对于素数 p,若 a是 p 的一个原根 , 则 :
a,a2, …,ap-1
关于 p 两两不同余 , 从而构成了 p 的非 0剩余类 ,即与 {1,2,…,(p-1)} 关于模 p 等价.
离散对数离散对数 若 a 是素数 p 的一个原根 , 则对任意整数 b,
b0 mod p,存在唯一的整数 i, 1i(p-1), 使得:
bai mod p
i 称为 b以 a 为基模 p 的指数 (离散对数 ), 记作inda,p(b). 容易知道 :
inda,p(xy)= [inda,p(x)+inda,p(y)] mod (p) inda,p(xr)= [rinda,p(x)] mod (p)
离散对数的计算 :ygx mod p
已知 g,x,p, 计算 y 是容易的 已知 y,g,p, 计算 x 是困难的
Diffie-HellmanDiffie-Hellman 密钥交换密钥交换 允许两个用户可以安全地交换一个秘密信息,用
于后续的通讯过程 算法的安全性依赖于计算离散对数的难度 算法:
双方选择素数 q 以及 q 的一个原根 r A 选择 X<q, 计算 XA=rXmod p, AB: XA B 选择 Y<q, 计算 YB=rYmod p, BA: YB A 计算 : (YB)X(rY)XrXYmod p B 计算 : (XA)Y(rX)YrXYmod p 双方获得一个共享密钥 (rXYmod p)
素数 q 以及 q 的原根 r 可由一方选择后发给对方
Diffie-HellmanDiffie-Hellman 密钥交换的攻击密钥交换的攻击 replay 攻击
中间人攻击图示
A BK = rxy
E
A BK = rxz
EK = ryz
Diffie-HellmanDiffie-Hellman 密钥交换的攻击密钥交换的攻击 中间人攻击
1 双方选择素数 q 以及 q 的一个原根 r(假定 E 知道 ) 2 A 选择 X<q, 计算 XA=rX mod p, AB: XA 3 E截获 XA,选 Z, 计算 ZE=rZ mod p,冒充 AB:ZE 4 B 选择 Y<q, 计算 YB=rY mod p, BA: YB 5 E截获 YB,冒充 BA: ZE 6 A 计算 : (ZE)X(rZ)XrZX mod p 7 B 计算 : (ZE)Y(rZ)YrYZ mod p 8 E 计算 : (XA)ZrXZ mod p, (YB)ZrYZ mod p
E无法计算出 rXY mod p E永远必须实时截获并冒充转发 , 否则会被发现
椭圆曲线密码介绍椭圆曲线密码介绍 1985年Miller,Koblitz 独立提出
y2+axy+by=x3+cx2+dx+e
曲线上的点连同无穷远点 O 的集合 运算定义:
若曲线三点在一条直线上 , 则其和为 O O 用作加法的单位: O = -O; P+O = P 一条竖直线交 X轴两点 P1、 P2 ,则 P1+P2+O=O ,于是 P1 = -P2
如果两个点 Q和 R的 X轴不同,则画一连线,得到第三点 P1 ,则 Q+R+P1=O ,即 Q+R=-P1
2倍,一个点 Q 的两倍是,找到它的切线与曲线的另一个交点 S ,于是 Q+Q=2Q=-S
椭圆曲线密码示意图椭圆曲线密码示意图
有限域上椭圆曲线有限域上椭圆曲线 有限域上椭圆曲线
y2x3+ax+b mod p p 是奇素数 , 且 4a3+27b20 mod p 针对所有的 0<= x <p ,可以求出有效的 y ,得到曲
线上的点 (x,y) ,其中 x,y < p。记为 Ep(a,b) Ep(a,b)中也包括 O
加法公式 : P+O=P 如果 P=(x,y) ,则 P+(x,-y)=O, (x,-y)点是 P 的负点,记为 -P。而且 (x,-y) 也在 Ep(a,b)中
如果 P=(x1,y1), Q=(x2,y2) ,则 P+Q=(x3,y3) 为x3=2-x1-x2 (mod p)y3=(x1-x3)-y1 (mod p)其中,如果 PQ ,则 = (y2-y1)/(x2-x1)
如果 P=Q ,则 = (3x12+a)/(2y1)
椭圆曲线用于加密椭圆曲线用于加密 找到一个难题:
考虑等式 Q=kP ,其中 Q、 P属于 Ep(a,b), k<p 已知 k和 P ,计算 Q ,是容易的 已知 Q和 P ,计算 k ,是困难的
选择 Ep(a,b) 的元素 G, 使得 G 的阶 n 是一个大素数 G 的阶是指满足 nG=O 的最小 n值
秘密选择整数 r ,计算 P=rG ,然后 公开 (p,a,b,G,P), P 为公钥 保密 r
加密 M :先把消息 M 变换成为 Ep(a,b)中一个点 Pm
然后,选择随机数 k ,计算密文 Cm={kG,Pm+kP) 如果 k 使得 kG或者 kP为 O ,则要重新选择 k.
解密 Cm: (Pm+kP)-r(kG)=Pm+krG-rkG=Pm
加密信息有扩张
椭圆曲线密码的安全性椭圆曲线密码的安全性 难点 : 从 P和 kP获得 k 对椭圆曲线研究的时间短 椭圆曲线要求密钥长度短 ,速度快 对比 : ECC RSA
*Pollard rho 分析方法Key size MIPS-Yrs
150 3.81010
205 7.11018
234 1.61028
512 3104
768 2108
1024 31011
1280 11014
1536 31016
2048 31020
消息认证消息认证 在网络通信中,有一些针对消息内容的攻击方法
伪造消息 窜改消息内容 改变消息顺序 消息重放或者延迟
消息认证:对收到的消息进行验证,证明确实是来自声称的发送方,并且没有被修改过。 如果在消息中加入时间及顺序信息,则可以完成对时
间和顺序的认证
消息认证的三种方式消息认证的三种方式 Message encryption :用整个消息的密
文作为认证标识 接收方必须能够识别错误
MAC :一个公开函数,加上一个密钥产生一个固定长度的值作为认证标识
Hash function :一个公开函数将任意长度的消息映射到一个固定长度的散列值,作为认证标识
Message Authentication CodeMessage Authentication Code 使用一个双方共享的秘密密钥生成一个固定大小
的小数据块,并加入到消息中,称 MAC ,或密码校验和 (cryptographic checksum)
用户 A 和用户 B ,共享密钥 K ,对于消息 M ,MAC=CK(M)
如果接收方计算的 MAC 与收到的 MAC匹配,则 接收者可以确信消息 M未被改变 接收者可以确信消息来自所声称的发送者 如果消息中含有序列号,则可以保证正确的消息顺序
MAC函数类似于加密函数,但不需要可逆性。因此在数学上比加密算法被攻击的弱点要少
MACMAC 应用方式应用方式
M
C
|| C
K
K
Compare
M
Ck(M)
关于关于 MACMAC 算法算法 MAC 不等于数字签名
因为通讯双方共享同一个密钥 MAC 有固定的长度 MAC 结构的重要性,例如,密钥足够长 + 加密
算法足够好安全 M=(X1,X2,…,Xt) 对M 产生校验核 M=X1X2…Xt
MAC = EK(M) 攻击者选择 M=(Y1,Y2,…,Yt-1,Yt), 使得 Yt 满足 :
Yt = Y1Y2…Yt-1M 于是 M=MEK(M)=EK(M) CK(M)=CK(M) 所以,尽管攻击者不知道 K ,仍然可以伪造消息 M
MACMAC 算法的要求算法的要求 条件:
攻击者知道MAC函数但不知道密钥 K
要求: 已知 M和 CK(M) ,要想构造 M 使得
CK(M)=CK(M) 在计算上不可行( 计算上无碰撞 )
CK(M)均匀分布:随机选择 M和M, Pr[CK(M) = CK(M)]=2-|MAC|
f是M 的一个变换 ( 例如对某些位取反 ),那么, Pr[CK(M)= CK(f(M))]=2-|MAC|
MAC based on DESMAC based on DES ANSI标准 (X9.17) 即为 CBC模式结构,初始
向量为 0 该方法适用于其他加密算法
算法: M=(X1,X2,…,Xt) M1=EK(X1) Mj+1=EK(Xj+1Mj), 1j<t MAC= Mt
Hash FunctionHash Function MAC 需要对全部数据进行加密
MAC速度慢 Hash 是一种直接产生认证码的方法 Hash函数 : h=H(x), 要求 :
可作用于任何尺寸数据且均产生定长输出 H(x) 能够快速计算 单向性 : 给定 h ,找到 x使 h=H(x) 在计算上不可行 Weak Collision Resistence(WCR):
给定 x ,找到 yx使 H(x)=H(y) 在计算上不可行 Strong Collision Resistence(SCR): 找到 yx使
H(x)=H(y) 在计算上不可行
生日攻击理论基础生日攻击理论基础 理论基础
若 k1.182m/22m/2, 则 k个在 [1,2m]的随机数中有两个数相等的概率不低于 0.5
若 k0.83n1/2,两个在 [1,n]的 k个随机数集合有交集的概率不小于 0.5
因此,当Hash 算法选用 N 位的 Hash值时,两组消息(选择 k=N/2)中有一对消息产生相同 Hash值的概率超过 0.5
生日攻击例子生日攻击例子
This Letter isI am writing
to introduceyou toto you
Mr.--
AlfredP.--
Barton, . . . . . .
Letter2与 Letter1中的信含义不同。各自组合出 2k封信件,然后在两个组中找到两封 hash值相同的信!
•Letter1:
•Letter2:. . . . . .
对策: Hash值足够长, 64-〉 128-〉 160-〉 256
hashhash函数通用模型函数通用模型 由Merkle 于 1989 年提出 几乎被所有 hash 算法采用 具体做法 :
把原始消息 M 分成一些固定长度的块 Yi
最后一块 padding并使其包含消息 M 的长度 设定初始值 CV0
压缩函数 f, CVi=f(CVi-1,Yi-1) 最后一个 CVi为 hash值
hashhash函数模型图函数模型图
b
Y0
nIV=CV0
f
b
Y1
n f
b
YL-1
n
CVL-1
f
CV1
n n
IV = initial value 初始值CV = chaining value 链接值Yi = ith input block (第 i 个输入数据块 )f = compression algorithm (压缩算法)n = length of hash code (散列码的长度 )b = length of input block(输入块的长度 )
CVL
MD5 MD5 算法算法 作者: Ron Rivest 算法
输入:任意长度的消息 输出: 128位消息摘要 处理:以 512位输入数据块为单位
MD5: MD5: 示意图示意图
MD5MD5 步骤步骤 第一步: padding
补长到 512 的倍数 最后 64位为消息长度的低 64位 一定要补长 (64+1~64+512) ,内容为 100…0
第二步 把结果分割为 512位的块: Y0,Y1,…YL-1
第三步 初始化MD buffer, 128位常量 (4 个字 ) ,进入循环迭代,共
L次 每次:一个输入 128位,另一个输入 512位,结果输出 128位
,用于下一轮输入 第四步
最后一步的输出即为散列结果 128位
MD5MD5 的每一步运算示意图的每一步运算示意图
每一轮中每一轮中 1616步的每一步运算结构步的每一步运算结构A B C D
A B C D
+
+
+
CLSs
+
g
X[k]
T[i]
Function g g(b,c,d)1 F(b,c,d) (bc)(bd)2 G(b,c,d) (bd)(cd)3 H(b,c,d) bcd4 I(b,c,d) c(bd)
关于关于 MD5MD5
MD5 使用 little-endian 生日攻击模式 +64位可计算 128位
hash值太短 MD5 不是足够安全的
Dobbertin 在 1996 年找到了两个不同的 512-bit块 ,它们在 MD5 计算下产生相同的 hash
至今还没有真正找到两个不同的消息 ,它们的MD5的 hash 相等
Secure Hash AlgorithmSecure Hash Algorithm 简简介介 1992年 NIST 制定了 SHA(128位 ) 1993年 SHA 成为标准 1994 年修改产生 SHA-1(160位 ) 1995年 SHA-1 成为新的标准 SHA-1 要求输入消息长度 <264
SHA-1 的摘要长度为 160位 基础是 MD4
SHA-1SHA-1 算法算法 结构与 MD5 类似 第一步: pading
与MD5 相同,补齐到 512 的倍数 第二步
分块 第三步
初始化MD buffer, 160位常量 (5 个字 ) 进入循环, 160输入 +512输入 -〉 160输出
第四步 最后的输出为 SHA-1 的结果
压缩函数压缩函数
每一轮中每一轮中 2020步的每一步运算结构步的每一步运算结构
常量
从消息块导出
SHA-1SHA-1 算法结论算法结论 SHA-1 使用 big-endian 抵抗生日攻击 : 160位 hash值 没有发现两个不同的 512-bit块 ,它们在
SHA-1 计算下产生相同的“ hash” 速度慢于 MD5 安全性优于 MD5
RIPEMD-160RIPEMD-160 简介简介 欧洲 RIPE项目的结果 RIPEMD 为 128位 更新后成为 RIPEMD-160 基础是 MD5 算法
输入:任意长度的消息 输出:长度为 160位的消息摘要 处理:以 512位数据块为单位
RIPEMD-160RIPEMD-160 的压缩函数的压缩函数
HMACHMAC 简介简介 MAC 可用块加密算法产生 MAC 算法速度慢 加密算法出口受限制 hash函数可用来构造 MAC: HMAC 为其中之一
HMACHMAC示意图示意图
HMACHMAC 的定义与特征的定义与特征 对密钥 K左边补 0 以产生一个 hash块 K+ K+每个字节与 ipad(00110110)作 XOR 以产生
Si
对 (Si||M) 进行 hash K+每个字节与 opad(01011010)作 XOR 以产生
S0
HMAC=f[IV,S0||f(IV,Si||M)] HMAC特征 :
可直接使用各种 hash 算法 可使用将来的更加安全和更加快速的 hash 算法 保持原始 hash 算法的性能 密钥的使用简单 与 hash函数有同等的安全性
数字签名数字签名 传统签名的基本特点 :
能与被签的文件在物理上不可分割 签名者不能否认自己的签名 签名不能被伪造 容易被验证
数字签名是传统签名的数字化 , 基本要求 : 能与所签文件“绑定” 签名者不能否认自己的签名 签名不能被伪造 容易被验证
数字签名方案数字签名方案 先对消息 M 作一个摘要 H(M) 然后发送方用自己的私钥对 H(M) 进行加密,得
到签名 EKRa(H(M)) 连同消息 M 一起,发送出去 B 收到复合的消息之后,把签名提取出来 B用 A 的公钥对签名解密得到 H’ B 计算所收到消息的摘要 H(M’) 如果 H’=H(M’) ,则消息确实是 A 产生的 问题
公钥的管理,公钥与身份的对应关系 签名的有效性,私钥丢失?
两种数字签名方案两种数字签名方案
加密算法的实现加密算法的实现 一些关键问题
算法的精确性,需要经过严格测试 找到权威的测试数据 注意字节的顺序 (big-endian和 little-endian)
算法的效率 局部运算的优化可以大大改进效率 大数的运算 一些技巧的使用,比如查表法
利用 C/C++语言的优化技术 局部地方采用汇编代码提高速度
库本身的安全性 专利问题
Crypto++Crypto++ Open-source 的加密算法库
最新版本为 4.2 多个编译器兼容
实现了几乎所有常用的算法 并且给出了各个算法的参考和引用
代码质量很高 算法实现的效率 代码本身、封装
已经增加了文档 维护,更新
例子:加密字符串例子:加密字符串char *EncryptString(const char *instr, const char *passPhrase){
unsigned int len=strlen(instr);char* outstr;
DefaultEncryptorWithMAC encryptor(passPhrase, new HexEncoder());
encryptor.Put((byte *)instr, len);encryptor.Close();
unsigned int outputLength = encryptor.MaxRetrieveable();outstr = new char[outputLength+1];encryptor.Get((byte *)outstr, outputLength);outstr[outputLength] = 0;return outstr;
}
例子:加解密文件例子:加解密文件void EncryptFile(const char *in, const char *out, const char *passPhrase){
FileSource f(in, true, new DefaultEncryptorWithMAC(passPhrase, new FileSink(out)));
}void DecryptFile(const char *in, const char *out, const char *passPhrase){
DefaultDecryptorWithMAC *p;FileSource file(in, false, p = new DefaultDecryptorWithMAC(passPhrase));file.Pump(256);if (p->CurrentState() != DefaultDecryptorWithMAC::KEY_GOOD){
cerr << "Incorrect passphrase.\n";return;
}
file.Attach(new FileSink(out));file.PumpAll();file.Close();if (p->CurrentState() != DefaultDecryptorWithMAC::MAC_GOOD)
cerr << "Invalid MAC. The file may have been tempered with.\n";}
例子:摘要例子:摘要void DigestFile(const char *filename){
MD5 md5;SHA shs;RIPEMD160 ripemd;BufferedTransformation *outputs[]={new HashFilter(md5),
new HashFilter(shs), new HashFilter(ripemd)};FileSource file(filename, true, new Fork(3, outputs));
cout << "MD5: ";outputs[0]->Attach(new HexEncoder(new FileSink(cout)));cout << endl;cout << "SHA: ";outputs[1]->Attach(new HexEncoder(new FileSink(cout)));cout << endl;cout << "RIPEMD-160: ";outputs[2]->Attach(new HexEncoder(new FileSink(cout)));cout << endl;
}
产生产生 RSARSA 公钥对公钥对void GenerateRSAKey(unsigned int keyLength, const char
*privFilename, const char *pubFilename, const char *seed)
{
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
HexEncoder privFile(new FileSink(privFilename));
priv.DEREncode(privFile);
privFile.Close();
RSAES_OAEP_SHA_Encryptor pub(priv);
HexEncoder pubFile(new FileSink(pubFilename));
pub.DEREncode(pubFile);
pubFile.Close();
}
例子:例子: RSARSA 加密加密char *RSAEncryptString(const char *pubFilename, const char *seed, const char *message){
FileSource pubFile(pubFilename, true, new HexDecoder);RSAES_OAEP_SHA_Encryptor pub(pubFile);
if (strlen(message) > pub.MaxPlainTextLength()) {cerr << "message too long for this key\n"; abort();
}RandomPool randPool;randPool.Put((byte *)seed, strlen(seed));char *outstr = new char[2*pub.CipherTextLength()+1];pub.Encrypt(randPool, (byte *)message, strlen(message), (byte *)outstr);
HexEncoder hexEncoder;hexEncoder.Put((byte *)outstr, pub.CipherTextLength());hexEncoder.Close();hexEncoder.Get((byte *)outstr, 2*pub.CipherTextLength());
outstr[2*pub.CipherTextLength()] = 0;return outstr;
}
例子:其他操作例子:其他操作void GzipFile(const char *in, const char *out, int deflate_level)
{
FileSource(in, true, new Gzip(deflate_level, new FileSink(out)));
}
void GunzipFile(const char *in, const char *out)
{
FileSource(in, true, new Gunzip(new FileSink(out)));
}
参考资料参考资料 书
William Stallings, Cryptography and network security: principles and practice, Second Edition.
Bruce Shneier, Applied cryptography: protocols, algorithms, and sourcecode in C, Second Edition.
文章 密码学的新方向
Web站点 http://www.eskimo.com/~weidai/cryptlib.html