RC4文件加密的python实现方法


Posted in Python onJune 30, 2015

本文实例讲述了RC4文件加密的python实现方法。分享给大家供大家参考。具体分析如下:

基于RC4流加密算法,使用扩展的16*16的S盒,32字节密钥。
目前应该是比较安全的。
 
刚学习python,好不容易调通了。
而且在VC和python下各实现了一遍,两个平台能够互相加解密,很有成就感的说。
 
下面是python3.0中的实现,在2.x下需要稍加修改。

# for python 3.0
# from 李勃
import struct,sys,os,binascii
"""
  RC4加密算法
  16*16 S盒
  加密单元:short
"""
def RC4(pkey,keylen,pin,dlen):
  N=65536
  S = list(range(N))
  j = 0
  for i in range(N):
    j = (j + S[i] + pkey[i%keylen])%N
    temp = S[i]
    S[i] = S[j]
    S[j] = temp
  i = j = 0
  pout= b''
  for x in range(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
def Coding(data):
  if(len(data)%2):
    data+=b'\0'
  dlen = len(data)//2
  return(struct.unpack(str(dlen)+'H',data))
# short->bytes
def unCoding(data):
  d=b''
  for i in range(len(data)):
    d += struct.pack('H',data[i])
  return(d)
#产生32字节密钥
def CreatKey(Keyt):
  pl = len(Keyt)
  Key=b''
  r=0
  for i in range(32):
    k=(Keyt[r%pl]+i)%256
    Key+= struct.pack('B',k)
    r+=1
  return Key
#更新密钥
def UpdataKey(Keyt):
  Key = unCoding(Keyt)
  #循环左移
  Key = Key[1:] + struct.pack('B',Key[0])
  tem=0
  #求和
  for i in range(len(Key)):
    tem += Key[i];
  Keyo=b''
  #Xor
  for i in range(len(Key)):
    Keyo += struct.pack('B',(Key[i]^tem)%256)
    tem += Keyo[i]>>3
    tem = tem % 256
  return(Coding(Keyo))
if __name__ == '__main__':
  #获得输入文件
  if len(sys.argv)==1:
    filename = input('源文件: ')
  else:
    filename = sys.argv[1]
   
  try:
    fin = open(filename,'rb')
  except:
    print('打开文件失败!')
    input()
    sys.exit()
  print(filename)
  #打开输出文件
  if filename[-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)
 
  #处理重名
  while os.path.exists(ofilename):
    ofilename = os.path.dirname(ofilename)+ '\\副本 '+ os.path.basename(ofilename)
  fout = open(ofilename,'wb')
  print(ofilename)
  #解密
  if eID==1:
    #读文件长度
    filelen = struct.unpack('I',fin.read(4))[0]
    print('FlieLen =',filelen,'\n......')
    while 1:
      #读块大小
      ps= fin.read(2)
      if not ps:
        #文件结束
        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]
      if binascii.crc32(x)!=crc:
        print('CRC32校验错误!',crc,binascii.crc32(x))
        input()
        sys.exit()
      fout.write(x)
    #裁剪末尾填充位
    fout.truncate(filelen)
  #加密
  elif eID==2:
    #获得文件长度
    fin.seek(0,2)
    filelen = fin.tell()
    print('FlieLen =',filelen,'\n......')
    fin.seek(0,0)
    fout.write(struct.pack('I',filelen))
    while 1:
      #读数据
      dd=fin.read(65534)
      if not dd:
        #文件结束
        break
      #末尾填充
      srl = len(dd)
      if srl%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程序设计有所帮助。

Python 相关文章推荐
Python求导数的方法
May 09 Python
python实现文本去重且不打乱原本顺序
Jan 26 Python
python查看微信好友是否删除自己
Dec 19 Python
python ftp 按目录结构上传下载的实现代码
Sep 12 Python
浅谈python requests 的put, post 请求参数的问题
Jan 02 Python
matplotlib实现显示伪彩色图像及色度条
Dec 07 Python
tensorflow指定CPU与GPU运算的方法实现
Apr 21 Python
Windows下PyCharm配置Anaconda环境(超详细教程)
Jul 31 Python
Django修改app名称和数据表迁移方案实现
Sep 17 Python
matplotlib交互式数据光标mpldatacursor的实现
Feb 03 Python
Python Numpy之linspace用法说明
Apr 17 Python
python Django框架快速入门教程(后台管理)
Jul 21 Python
详解Python中的序列化与反序列化的使用
Jun 30 #Python
Python中函数的参数传递与可变长参数介绍
Jun 30 #Python
python实现文件快照加密保护的方法
Jun 30 #Python
Python实现高效求解素数代码实例
Jun 30 #Python
python实现DES加密解密方法实例详解
Jun 30 #Python
python实现的系统实用log类实例
Jun 30 #Python
python实现在windows服务中新建进程的方法
Jun 30 #Python
You might like
用PHP+java实现自动新闻滚动窗口
2006/10/09 PHP
PHP MySQL应用中使用XOR运算加密算法分享
2011/08/28 PHP
CI框架装载器Loader.php源码分析
2014/11/04 PHP
PHP使用gmdate实现将一个UNIX 时间格式化成GMT文本的方法
2015/03/19 PHP
PHP设计模式之迭代器模式
2016/06/17 PHP
jQuery+CSS 实现的超Sexy下拉菜单
2010/01/17 Javascript
JQuery的Alert消息框插件使用介绍
2010/10/09 Javascript
Js日期选择器并自动加入到输入框中示例代码
2013/08/02 Javascript
详解JavaScript基本类型和引用类型
2015/12/09 Javascript
学习JavaScript设计模式之迭代器模式
2016/01/19 Javascript
快速掌握Node.js事件驱动模型
2016/03/21 Javascript
微信小程序 参数传递详解
2016/10/24 Javascript
使用JSON作为函数的参数的优缺点
2016/10/27 Javascript
快速掌握jQuery插件WebUploader文件上传
2016/11/07 Javascript
AngularJS全局scope与Isolate scope通信用法示例
2016/11/22 Javascript
React.js中常用的ES6写法总结(推荐)
2017/05/09 Javascript
angular.js指令中的controller、compile与link函数的不同之处
2017/05/10 Javascript
Angular2入门教程之模块和组件详解
2017/05/28 Javascript
Vue 2.0学习笔记之Vue中的computed属性
2017/10/16 Javascript
Vue+webpack项目基础配置教程
2018/02/12 Javascript
Vue js 的生命周期(看了就懂)(推荐)
2019/03/29 Javascript
layui复选框的全选与取消实现方法
2019/09/02 Javascript
Vue-cli4 配置 element-ui 按需引入操作
2020/09/11 Javascript
vue-cli中实现响应式布局的方法
2021/03/02 Vue.js
[01:10:58]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第二场 6.2
2018/06/03 DOTA
python 实现归并排序算法
2012/06/05 Python
用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动
2015/11/05 Python
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
Flask实现图片的上传、下载及展示示例代码
2018/08/03 Python
解决django接口无法通过ip进行访问的问题
2020/03/27 Python
Python实现Wordcloud生成词云图的示例
2020/03/30 Python
python批量生成条形码的示例
2020/10/10 Python
HTML5时代CSS设置漂亮字体取代图片
2014/09/04 HTML / CSS
二十年同学聚会致辞
2015/07/28 职场文书
django如何自定义manage.py管理命令
2021/04/27 Python
CSS的calc函数用法小结
2022/06/25 HTML / CSS