密码学——公钥密码体系之背包算法1

Posted 摆渡沧桑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了密码学——公钥密码体系之背包算法1相关的知识,希望对你有一定的参考价值。

密码学——公钥密码体系之背包算法1

众所周知,公钥密码,又称非对称密码,比较常见的是基于以下三种数学难题的公钥密码体制;

  1. 大数因子分解难解性(RSA)
  2. 离散对数难解性(ElGamal)
  3. 椭圆曲线离散对数难解性(ECC)

1.背包算法

本次介绍的并不是以上三种类型的公钥密码体制,而是在公钥密码出现之前,就已经存在的公开密码加密算法:背包算法;
背包算法是由Merkle和Hellman开发的背包算法。只能用于加密,后来由Shamir将它改进,使之也能用于数字签名;

背包算法的安全性起源于背包难题,他是一个NP完全问题,但后来发现该算法并不安全,但是由于它证明了如何将NP完全问题用于公开秘钥密码学,因此,值得去学习。

下面介绍一下什么是背包算法:
描述:给定一个物品,每个重量不同,能否将这些物品中的几件放入一个背包中,使之等于一个给定的重量?
公式化描述:给定一系列值M1,M2,…,Mn,和一个S值,计算bi,使之满足:
S = b 1 M 1 + b 2 M 2 + . . . + b n M n S = b1 M1 + b2M2 + ... + bnMn S=b1M1+b2M2+...+bnMn
b i bi bi值可为0,1。1表示这个物品在背包中,0表示不存在;

举一个简单的例子:
这些物品可能分别重1、5、6、11、14、20,可以用5、6和11组装为一个重为22的背包,而组装一个重为24的背包则是不可能的。
一般来说,解决这个问题所需要的的时间似乎是随着物品个数的增加,呈指数增长;

Merkle-Hellman背包算法的思想是将消息编码为背包问题的解。明文分组长度等于堆中物品的个数,并且明文位与b的值相对应,密文则是计算得到的和值,下图给出了一段用例子中背包问题来加密的明文;
在这里插入图片描述
背包实际上存在两类不同的背包问题:

  1. 线性时间内可解;
  2. 线性时间内不可解;
    容易解的背包问题可以修改成难解的背包问题。公开秘钥使用难解的背包问题,可以很容易的用来加密明文,但不能用来解密密文,私人秘钥用容易解的背包问题,他给出一个解密的简单方法。不知道私人秘钥的人要破解密文,必须解一个难得背包问题。

2.超递增背包

对于易解的背包问题,可以选择超递增序列,那么相应的背包问题容易求解。
超递增序列:它的每一项都大于它之前所有项之和,例如{1,3,6,13,27,52}是一个超递增序列,而{1,3,4,9,15,25}则不是。

超递增背包问题的解很容易找到,计算其总量并与序列中最大的数比较,如果总重量小于这个数,则它不在背包中,如果总重量大于这个数,则它在背包中,背包重量减去这个数,进而考察序列中下一个最大的数,重复直到结束。如果总重量减为0,那么只有一个解,否则,无解。

例如,总重量为70的一个背包,超递增序列为{2,3,6,13,27,52};最大重量为52,小于70,所以52在背包中,70-52 = 18,下一个重量27 >18,因此,27不在背包中,在下一个13<18,13在背包中,18-13 = 5,以此类推,再下一个,3与2均在背包中,总重量减为0,表明已求出一个解,如果这个一个M-H背包加密分组,那么对应的密文70的解为110101.

非超递增序列的背包是困难的问题,它们没有快速算法。要决定哪一项在背包中的唯一方法,是依次测试所有解,直到你得到正确的解为止。最快的算法仍随背包中物品超递增问题困难,对于后者,当你加入一项到序列中,求解只需要再进行一次运算。

Merkle-Hellman背包算法就是利用这个性质。私人秘钥是一个超递增背包问题的重量序列。公开秘钥是有相同解的普通背包问题的序列,Merkle和Hellman设计了一种方法可将超递增背包问题转化为普通的背包问题,它们用模运算来完成此变化。

3.私人秘钥产生公开秘钥

下面说明如何由背包算法由私人秘钥产生公开秘钥:
取一个递增序列,如 {2,3,6,13,27,52},用n去乘所有的项,再用m做模数进行模运算,这个模数应比序列中所有的数的和还要大,如105。乘数应与序列中的任何一个数没有公因子,比如31。因此,一般的背包序列为:

2*31 mod105  = 62
3*31 mod105  = 93
6*31 mod105  = 81
13*31 mod105  = 88
27*31 mod105  = 102
52*31 mod105  = 37

因此,得到的背包为{62,93,81,88,102,37}。
超递增背包序列就是私人秘钥,而得到的背包序列就是公开秘钥。

4.加密过程

要加密一个二进制的消息,首先将它分成长度等于背包序列中详述的许多分组。然后,用1表示该项存在,用0表示该项不存在,计算背包的总重量。对所有分组都重复这个运算。
例如,如果消息是二进制数011000110101101110,采用上面的背包算法的加密过程如下:

消息 = 011000 110101 101110
011000对应 93 + 81 = 174
110101对应 62 + 93 + 88 + 37 = 280
101110对应 62 + 81 + 88 + 102 = 333

因此,密文为 174, 280, 333

5.解密过程

接收者直到私人秘钥:原始的超递增背包、用于把它转换成一般背包的n和m的值,为解密消息,接收者必须首先计算出 n − 1 n^{-1} n1以满足 n ∗ n − 1 = = 1 m o d m n*n^{-1} == 1 mod m nn1==1modm。用 n − 1 n^{-1} n1模m乘密文值得每项,然后用私人背包对它进行划分就可获得明文。

在本例中,超递增背包:
{2,3,6,13,27,52}
m = 105, n = 31,密文消息为174,280,333。 n − 1 = 61 n^{-1} = 61 n1=61,所以密文值必须用61模105乘。
174 * 61 mod 105 = 9 = 3 + 6 对应0111000;
280 * 61 mod 105 = 70 = 2 + 3 + 13 + 52 对应110101;
333 * 61 mod 105 = 48 = 2 + 6 + 13 + 27 对应0111000;
因此,恢复出的明文为011000 110101 101110

6.实际的实现方案

要解决仅有6项背包序列的问题不是很难,甚至对非超增序列也是一样。实际使用的背包算法至少应该包含250项。在超递增背包中,每项值一般为200~400位。模数一般为100 ~ 200位。该算法在实际使用中,用随机序列发生器来产生这些值。

对这样的背包,试图用穷举攻击来破译是无用的。即使一台计算机每秒能计算100万次,试完所有可能的背包值,也需要 1 0 46 10^{46} 1046年。

7.背包的安全性

既然上面说了即使使用穷举攻击无法破译,那么为什么该算法被证明还是可以破解?
Shamir支出某些情况下,背包算法能被破译,具体可以查阅相关文献。

以上是关于密码学——公钥密码体系之背包算法1的主要内容,如果未能解决你的问题,请参考以下文章

密码学之公钥密码体系:RSA算法

密码学——公钥密码体系之RSA算法2

密码学——公钥密码体系之RSA算法2

密码学之公钥密码体系:ElGamal算法

密码学之公钥密码体系:ElGamal算法

密码学之公钥密码体系:ElGamal算法