RC4文件加密的python实现方法
本文实例讲述了RC4文件加密的python实现方法。分享给大家供大家参考。具体分析如下:
基于RC4流加密算法,使用扩展的16*16的S盒,32字节密钥。
目前应该是比较安全的。
刚学习python,好不容易调通了。
而且在VC和python下各实现了一遍,两个平台能够互相加解密,很有成就感的说。
下面是python3.0中的实现,在2.x下需要稍加修改。
#forpython3.0
#from李勃
importstruct,sys,os,binascii
"""
RC4加密算法
16*16S盒
加密单元:short
"""
defRC4(pkey,keylen,pin,dlen):
N=65536
S=list(range(N))
j=0
foriinrange(N):
j=(j+S[i]+pkey[i%keylen])%N
temp=S[i]
S[i]=S[j]
S[j]=temp
i=j=0
pout=b''
forxinrange(dlen):
i=i+1
j=(j+S[i])%N
temp=S[i]
S[i]=S[j]
S[j]=temp
pout+=struct.pack('H',pin[x]^S[(S[i]+S[j])%N])
return(pout)
#bytes->short
defCoding(data):
if(len(data)%2):
data+=b'\0'
dlen=len(data)//2
return(struct.unpack(str(dlen)+'H',data))
#short->bytes
defunCoding(data):
d=b''
foriinrange(len(data)):
d+=struct.pack('H',data[i])
return(d)
#产生32字节密钥
defCreatKey(Keyt):
pl=len(Keyt)
Key=b''
r=0
foriinrange(32):
k=(Keyt[r%pl]+i)%256
Key+=struct.pack('B',k)
r+=1
returnKey
#更新密钥
defUpdataKey(Keyt):
Key=unCoding(Keyt)
#循环左移
Key=Key[1:]+struct.pack('B',Key[0])
tem=0
#求和
foriinrange(len(Key)):
tem+=Key[i];
Keyo=b''
#Xor
foriinrange(len(Key)):
Keyo+=struct.pack('B',(Key[i]^tem)%256)
tem+=Keyo[i]>>3
tem=tem%256
return(Coding(Keyo))
if__name__=='__main__':
#获得输入文件
iflen(sys.argv)==1:
filename=input('源文件:')
else:
filename=sys.argv[1]
try:
fin=open(filename,'rb')
except:
print('打开文件失败!')
input()
sys.exit()
print(filename)
#打开输出文件
iffilename[-4:]=='.RC4':
eID=1
key=input('输入解密密钥:').encode()
ofilename=filename[:-4]
else:
eID=2
key=input('输入加密密钥:').encode()
ofilename=filename+'.RC4'
key=Coding(CreatKey(key))
key=UpdataKey(key)
#处理重名
whileos.path.exists(ofilename):
ofilename=os.path.dirname(ofilename)+'\\副本'+os.path.basename(ofilename)
fout=open(ofilename,'wb')
print(ofilename)
#解密
ifeID==1:
#读文件长度
filelen=struct.unpack('I',fin.read(4))[0]
print('FlieLen=',filelen,'\n......')
while1:
#读块大小
ps=fin.read(2)
ifnotps:
#文件结束
break
packsize=struct.unpack('H',ps)[0]
#读数据
dd=fin.read(packsize)
#解密
dd=Coding(dd)
x=RC4(key,len(key),dd,len(dd))
key=UpdataKey(key)
#crc
crc=struct.unpack('I',fin.read(4))[0]
ifbinascii.crc32(x)!=crc:
print('CRC32校验错误!',crc,binascii.crc32(x))
input()
sys.exit()
fout.write(x)
#裁剪末尾填充位
fout.truncate(filelen)
#加密
elifeID==2:
#获得文件长度
fin.seek(0,2)
filelen=fin.tell()
print('FlieLen=',filelen,'\n......')
fin.seek(0,0)
fout.write(struct.pack('I',filelen))
while1:
#读数据
dd=fin.read(65534)
ifnotdd:
#文件结束
break
#末尾填充
srl=len(dd)
ifsrl%2:
srl+=1;
dd+=b'\0'
#crc
crc=struct.pack('I',binascii.crc32(dd))
#加密数据
dd=Coding(dd)
x=RC4(key,len(key),dd,len(dd))
key=UpdataKey(key)
#写入文件
fout.write(struct.pack('H',srl))
fout.write(x)
fout.write(crc)
fin.close()
fout.close()
print('OK!')
input()
希望本文所述对大家的Python程序设计有所帮助。