hdml指的是什么接口
500
2022-10-05
RSA签名伪造(rsa加密数字签名)
RSA签名伪造
在使用RSA签名的时候,不要对明文进行签名,而是要对HASH值进行签名
原因是对明文签名,容易被伪造,坏人可以使用M=m1*m2 mod N
然后,再用m1的签名* m2的签名=M的签名
因为:
C1=m1d mod N 签名1
C2=m2d mod N 签名2
C1*C2=(m1*m2)d mod N =Md mod N 坏人想要得到的签名M
而HASH没有hash(m1)*hash(m2)=hash(m)这样的等式
程序构造如下:
importrandom
importsys
#####################################################
#通过m1和m2的签名,伪造M=m1*m2 mod n 情况下的M的签名
#所以,不要对明文进行签名
#####################################################
classRSA:
def __init__(self):
self.p=0#大素数P
self.q=0#大素数Q
self.n=0#p*q
self.nx=0#(p-1)*(q-1)
self.e=0#公钥
self.d=0#私钥
temp_str='#,!,,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z'
self.str_list=temp_str.split(',')
#####################################################
#计算a*b%n
#####################################################
def ModMul(self,a,b,n):
res=0
while(b):
if(b&1): #b是奇数
res=(res+a)%n
a=(a+a)%n
b=b>>1 #b 除以2
return res
#####################################################
#a^b % n
#####################################################
def ModExp(self,a,b,n):
res=1
while(b):
if(b&1): #b是奇数
res=self.ModMul(res,a,n) #res*amod n
a=self.ModMul(a,a,n)
b=b>>1 #b 除以2
return res
#####################################################
def gcd(self,n,m):
if n%m ==0:
return m
else:
return self.gcd(m,n%m)
#####################################################
#计算e,辗转相除法,e与nx是互素的
#####################################################
def CalculationE(self,nx):
y=random.randint(3, nx-1)
while self.gcd(nx,y)!=1:
y=random.randint(3, nx-1)
return y
#####################################################
#扩展的欧几里德算法
#####################################################
def EGcd(self,q,x1,x2,x3,y1,y2,y3):
if y3==0:
return 0
else:
if int(y3)==1:
return y2
else:
q=x3//y3
t1=x1-q*y1
t2=x2-q*y2
t3=x3-q*y3
x1=y1
x2=y2
x3=y3
y1=t1
y2=t2
y3=t3
returnself.EGcd(q,x1,x2,x3,y1,y2,y3)
#####################################################
#加解密测试
#####################################################
def Encrypt(self,stringM,key):
#将字符串stringM转换为列表lm
lm=[]
for x in stringM:
pos=self.str_list.index(x.upper())
lm.append(pos)
#将每个字符的ASC值加密存入lc
lc=[]
stringC=''
for m in lm:
mx=self.ModExp(m,key,self.n)
#print(str(m)+'--->'+str(mx))
lc.append(mx)
stringC+=str(mx)+','
return stringC
#####################################################
def Decrypt(self,stringC,key):
#将密文解密,存入lx列表中
lc=stringC.split(',')
lx=[]
for i in range(0,len(lc)-1):
#print(lc[i])
lx.append(self.ModExp(int(lc[i]),key,self.n)) #将列表转换为字符串并输出
#print(self.ModExp(int(lc[i]),key,self.n))
string=''
for ch in lx:
string+=self.str_list[ch]
return(string)
#####################################################
defmain():
if len(sys.argv) !=5:
print("Usage: " + sys.argv[0]+" user pass keyrefer_file month")
sys.exit()
m1=sys.argv[3]
m2=sys.argv[4]
#m=m1*m2
s=RSA()
s.p=int(sys.argv[1])
print("素数P: ",s.p)
s.q=int(sys.argv[2])
print("素数Q: ",s.q)
s.n=s.p*s.q
print("P与Q乘积: ",s.n)
s.nx=(s.p-1)*(s.q-1)
print("(p-1)*(q-1) ",s.nx)
s.e=s.CalculationE(s.nx)
print("e ",s.e)
s.d=s.EGcd(0,1,0,s.nx,0,1,s.e)
if s.d<0:
s.d=s.nx+s.d
while s.d==0:
s.e=s.CalculationE(s.nx)
s.d=s.EGcd(0,1,0,s.nx,0,1,s.e)
if s.d<0:
#print(s.d)
s.d=s.n+s.d
print("d ",s.d)
#################签名
c1=s.Encrypt(m1,s.d)
print('签名m1:',c1)
v1=s.Decrypt(c1,s.e)
print('验证m1:',v1)
c2=s.Encrypt(m2,s.d)
print('签名m2:',c2)
v2=s.Decrypt(c2,s.e)
print('验证m2:',v2)
m=''
if len(m1)==len(m2):
for i in range(0,len(m1)):
pos1=s.str_list.index(m1[i].upper())
pos2=s.str_list.index(m2[i].upper())
pos3=pos1*pos2 %(len(s.str_list))
m+=s.str_list[pos3]
print('伪造JJ的签名,使用私钥加密的(m1)*使用私钥加密的(m2) mod s.n:')
c1_list=c1.split(',')
c2_list=c2.split(',')
c_list=[]
for k in range(0,len(c1_list)-1):
c1_pos=int(c1_list[k])
c2_pos=int(c2_list[k])
c_pos=(c1_pos*c2_pos)% s.n
c_list.append(c_pos)
print(c_list)
temp_key=input('正确的M的签名,使用私钥加密,按任意键继续')
c=s.Encrypt(m,s.d)
print('签名m:',c)
v=s.Decrypt(c,s.e)
print('验证m:',v)
if__name__=="__main__":
main()
输出如下:
C:\Users\citdc-jeff>python3E:\Python\crypto\RSA\rsa_sign_fake.py 7 11 ab cd
素数P: 7
素数Q: 11
P与Q乘积: 77
(p-1)*(q-1) 60
e 11
d 11
签名m1: 47,37,
验证m1: AB
签名m2: 38,6,
验证m2: CD
伪造JJ的签名,使用私钥加密的(m1)*使用私钥加密的(m2) mod s.n:
使用m1的签名 47,37
使用m2的签名 38,6
构造M的签名 47*38 mod 77=15
37*6 mod77=67
所以M的签名为15,67
使用正确的M的签名验证
签名m: 15,68,
验证m: MV
所以坏人可以让用户签名m1 和m2 ,来达到获取M签名的目的
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~