背包密码,rsa的p-1光滑

背包密码原理

这里概括为a1~an的n个数字代表字符,然后前面的字符来源于需要加密的明文的二进制形式对应作为其系数然后累加其结果就是其加密后的密文。
详细:https://ctf-wiki.org/crypto/asymmetric/knapsack/knapsack/
img
这里阐述了背包密码的背包向量的生成原理,即为了其密文加密后能够被正常解密,其生成的序列应该为超递增序列。
加密的过程采取ctfwiki的解释:
img
意思也就是说,会先生成一队超递增序列作为私钥,并寻找到一个大于超递增序列所有数之和的数m作为模数,,然后寻找到一个w满足gcd(w,m)==1的数字作为乘数,从而生成新的超递增序列作为新的背包向量b,然后b和m作为公钥,a和w作为私钥。
解密就是使用乘数的逆元跟加密后的每个密文相乘再进行累加求和得到明文的长字节。
破解的方法这里讲一下wiki上的破解方法,实际上还有LLL这个算法可以进行破解:
https://blog.csdn.net/XiongSiqi_blog/article/details/132109655
这里讲了背包密码的LLL攻击方法。
这里我讲一下最原本的wiki上面,就是破解并不需要找到原本的w和m,而是找到一对w和m然后让这个公钥背包向量能够生成一个新的超递增序列,然后使用这个新找到的一组数据进行原本的模样的解密。
脚本参考(wiki上的):

#LLL破解攻击方法
import binascii
# open the public key and strip the spaces so we have a decent array
fileKey = open("pub.Key", 'rb')
pubKey = fileKey.read().replace(' ', '').replace('L', '').strip('[]').split(',')
nbit = len(pubKey)
# open the encoded message
fileEnc = open("enc.txt", 'rb')
encoded = fileEnc.read().replace('L', '')
print "start"
# create a large matrix of 0's (dimensions are public key length +1)
A = Matrix(ZZ, nbit + 1, nbit + 1)
# fill in the identity matrix
for i in xrange(nbit):
    A[i, i] = 1
# replace the bottom row with your public key
for i in xrange(nbit):
    A[i, nbit] = pubKey[i]
# last element is the encoded message
A[nbit, nbit] = -int(encoded)

res = A.LLL()
for i in range(0, nbit + 1):
    # print solution
    M = res.row(i).list()
    flag = True
    for m in M:
        if m != 0 and m != 1:
            flag = False
            break
    if flag:
        print i, M
        M = ''.join(str(j) for j in M)
        # remove the last bit
        M = M[:-1]
        M = hex(int(M, 2))[2:-1]
        print M

p-1光滑

首先是光滑数的定义:
img
这里wiki上写的太简洁了,反而有点难看懂,其实就是:
假设有个跟p互质的数字a那么就存在一个af(p)的函数再(modp)的环条件下,使得af(p)恒等价于1,于是就有一个条件整数k满足kp+1=af(p)成立,于是也就有af(p)-1=kxp,于是就推导出来了af(p)于pk成一个线性关系。
img
先看最后一个式子,gcd(aM-1,N)可以对n进行分解,分解得到p和q,这个aM实际上是af(p)-1近似代换之后这个式子其实就是gcd(kp,N)进行求解,然后N本身就是pq,首先两者都是跟p得乘积,然后使用gcd会讲N分解为其多个因数之间的乘法等式,比如7=1x7……0,7=2x3……1,7=3x2……1,7=1x7……0,这里不进行扩展推导,最终结论就是,只有pq的最后结果是余数是0,然后其的乘积是pq,其余的余数要么是1,要么是0。最后也就有
img
图片上的M并不是指明文,而是指以上的各种数字的关系,为了方便计算,最后变化为了gcd(a^n-1,N)的结果,n取2..正无穷,一步步遍历,直到使得题目提供的N被成功分解,然后再用分解得到的值进行RSA解密,于是就可以得到其的明文数据m。
wiki脚本如下:

from gmpy2 import *
a = 2
n = 2
while True:
    a = powmod(a, n, N)
    res = gcd(a-1, N)
    if res != 1 and res != N:
        q = N // res
        d = invert(e, (res-1)*(q-1))
        m = powmod(c, d, N)
        print(m)
        break
    n += 1

应用参考wiki列题,但是wiki上面的并不是p-1光滑而是p+1光滑。wiki面对p+1光滑直接般脚本了,因为p+1光滑数学式子相对复杂。

posted @ 2025-04-27 12:25  喵老师哒哟  阅读(43)  评论(0)    收藏  举报