现代密码学 实验
2015-12-21 21:39
896 查看
学了一门课 ,叫《现代密码学》,做实验要实现AES加密文件,RSA加密AES秘钥,然后再反向解密出来,模拟的过程如下:
Alice先加密!
加密过程:
之后Bob再解密!
解密过程:
鉴于是个学渣,用到的RSA,AES,MD5算法都只是大概了解一下,并没有花心思去实现,而且密码学老师给的密码库并不会用,所以,在另外一位同学的建议下,用了只是知道一点点的python来实现,因为有两个挺好的密码库来用 pycrypto M2crypto
过程很曲折,轻易勿模仿!
之后是实验报告
实验报告
一、 设计思路
加密:
Alice拥有: AES秘钥,Bob公钥,Alice的私钥
解密:
Bob拥有:Alice的公钥,Bob的私钥
二、 程序结构
采用python编写,用到两个加解密库:pycrypto,M2crypto
main.py 主函数,调用其他函数
functions.py 具体函数的实现
三、 函数代码
① # AES加密
def aes_encrypt(aes_file, key,iv): #aes_file 文件,key 16-bytes 对称秘钥
from Crypto.Cipher import AES
from Crypto import Random
cipher = AES.new(key, AES.MODE_OFB,iv) # 生成了加密时需要的实际密码,这里采用OFB模式
# if fs is a multiple of 16
x = len(aes_file) % 16
print '要加密文件的长度是: ', len(aes_file)
print '需要填充的数据长度 : ',(16- x)%16
if x != 0:
aes_file_pad = aes_file + '0'*(16 - x)# It should be 16-x
else:
aes_file_pad=aes_file
msg = cipher.encrypt(aes_file_pad)
return msg,(16- x)%16
② # AES解密
def aes_decrypt(aes_file, key,iv):
from Crypto.Cipher import AES
cipher = AES.new(key, AES.MODE_OFB,iv) # 生成了解密时需要的实际密码,这里采用OFB模式
msg=cipher.decrypt(aes_file)
return msg
③# 计算MD5值
def md5_encrypt(md5_file):
from Crypto.Hash import MD5
msg = MD5.new()
msg.update(md5_file)
return msg.hexdigest()
④# RSA私钥加密
def rsa_private_encrypt(msg,file_rsa_private_key_name):
from M2Crypto import RSA # 用M2Crypto下的RSA模块
rsa_private_key=RSA.load_key(file_rsa_private_key_name)
msg_encrypted=rsa_private_key.private_encrypt(msg,RSA.pkcs1_padding)
return msg_encrypted
RSA公钥加密、私钥解密、公钥解密与此类似
四、 问题解决
1. 采用AES加密CFB(输出反馈模式),需要初始化加密模块,生成16位的iv,需要给Bob发送,可以跟AES秘钥一样采用RSA加密
2. 读入字符串时,区别raw_input(),input(),只能用前者
原因:input会把输入的字符串当做一个变量名
3.AES加密时遇到数据块不足一整块情况,会进行填充,这样导致内容发生变化,以致解密出的文件与原文件MD5不一致,故需把填充位数发送给Bob,解密时可去掉填充部分
五、 参考网页
环境配置(建议自己用virtualenv配置一个虚拟python环境):
Python安装:
http://jingyan.baidu.com/article/7908e85c78c743af491ad261.html
或者http://www.runoob.com/python/python-install.html
两个库安装(直接使用pip):
pip install pycrypto
pip install --egg M2CryptoWin32
再之后是乱乱的代码
main.py
functions.py
变量命名过长(没什么办法啊,组织能力不够)
Alice先加密!
加密过程:
之后Bob再解密!
解密过程:
鉴于是个学渣,用到的RSA,AES,MD5算法都只是大概了解一下,并没有花心思去实现,而且密码学老师给的密码库并不会用,所以,在另外一位同学的建议下,用了只是知道一点点的python来实现,因为有两个挺好的密码库来用 pycrypto M2crypto
过程很曲折,轻易勿模仿!
之后是实验报告
实验报告
一、 设计思路
加密:
Alice拥有: AES秘钥,Bob公钥,Alice的私钥
解密:
Bob拥有:Alice的公钥,Bob的私钥
二、 程序结构
采用python编写,用到两个加解密库:pycrypto,M2crypto
main.py 主函数,调用其他函数
functions.py 具体函数的实现
三、 函数代码
① # AES加密
def aes_encrypt(aes_file, key,iv): #aes_file 文件,key 16-bytes 对称秘钥
from Crypto.Cipher import AES
from Crypto import Random
cipher = AES.new(key, AES.MODE_OFB,iv) # 生成了加密时需要的实际密码,这里采用OFB模式
# if fs is a multiple of 16
x = len(aes_file) % 16
print '要加密文件的长度是: ', len(aes_file)
print '需要填充的数据长度 : ',(16- x)%16
if x != 0:
aes_file_pad = aes_file + '0'*(16 - x)# It should be 16-x
else:
aes_file_pad=aes_file
msg = cipher.encrypt(aes_file_pad)
return msg,(16- x)%16
② # AES解密
def aes_decrypt(aes_file, key,iv):
from Crypto.Cipher import AES
cipher = AES.new(key, AES.MODE_OFB,iv) # 生成了解密时需要的实际密码,这里采用OFB模式
msg=cipher.decrypt(aes_file)
return msg
③# 计算MD5值
def md5_encrypt(md5_file):
from Crypto.Hash import MD5
msg = MD5.new()
msg.update(md5_file)
return msg.hexdigest()
④# RSA私钥加密
def rsa_private_encrypt(msg,file_rsa_private_key_name):
from M2Crypto import RSA # 用M2Crypto下的RSA模块
rsa_private_key=RSA.load_key(file_rsa_private_key_name)
msg_encrypted=rsa_private_key.private_encrypt(msg,RSA.pkcs1_padding)
return msg_encrypted
RSA公钥加密、私钥解密、公钥解密与此类似
四、 问题解决
1. 采用AES加密CFB(输出反馈模式),需要初始化加密模块,生成16位的iv,需要给Bob发送,可以跟AES秘钥一样采用RSA加密
2. 读入字符串时,区别raw_input(),input(),只能用前者
原因:input会把输入的字符串当做一个变量名
3.AES加密时遇到数据块不足一整块情况,会进行填充,这样导致内容发生变化,以致解密出的文件与原文件MD5不一致,故需把填充位数发送给Bob,解密时可去掉填充部分
五、 参考网页
基本python语法:(这网站挺好的)
http://www.runoob.com/python/python-tutorial.html
关于命令行显示:http://jingyan.baidu.com/article/925f8cb8e00554c0dde0562b.html
pycrypto库说明:(MD5例子在此找到)
https://pythonhosted.org/pycrypto/
M2crypto库说明:
http://www.heikkitoivonen.net/m2crypto/api/
实现AES:
http://blog.chinaunix.net/uid-26275986-id-4349364.html
实现RSA:
http://my.oschina.net/kuaikuai/blog/208075?fromerr=rMpqv2p4
生成RSA公钥秘钥:
http://codego.net/438504/
环境配置(建议自己用virtualenv配置一个虚拟python环境):
Python安装:
http://jingyan.baidu.com/article/7908e85c78c743af491ad261.html
或者http://www.runoob.com/python/python-install.html
两个库安装(直接使用pip):
pip install pycrypto
pip install --egg M2CryptoWin32
再之后是乱乱的代码
main.py
# coding:utf8 import functions from functions import file_encrypt, file_decrypt, printCN, raw_inputCN while 1: # 相当于主程序了。。。 printCN("这是一个加解密文件程序,请按照提示输入!\n") printCN("请选择:\n1.加密文件 2.解密文件 3.退出") select = input() if select == 1: file_encrypt() break elif select == 2: file_decrypt() break else: break
functions.py
# coding:utf8 # 终端输出中文不乱码 def printCN(str1): print(str1.decode("utf8")) def raw_inputCN(str1): return raw_input(str1.decode("utf8").encode("gbk")) def file_encrypt(): printCN("请把以下文件放在与此程序同一路径下") printCN("1.要加密的文件") printCN("2.AES秘钥文件") printCN("3.你的RSA私钥文件") printCN("4.接收者的RSA公钥文件") raw_inputCN("放好之后,回车继续\n") file_name=raw_inputCN("请输入要加密的文件名:\n") file_aes_key_name=raw_inputCN("请输入AES秘钥文件名:\n") file=open(file_name,'rb') # 打开要加密文件 file_msg=file.read() file_aes_key=open(file_aes_key_name,'rb') # 打开AES秘钥文件 aes_key=file_aes_key.read() from Crypto.Cipher import AES from Crypto import Random # iv用来记录AES随机生成的一个16字节初始向量 iv = Random.new().read(AES.block_size) # 使用Crypto中Random模块,读取16字节数据作为iv的值,AES分块大小固定为16字节 printCN("开始对原文件进行AES加密......") file_encrypted_msg,fill_number=aes_encrypt(file_msg,aes_key,iv) # 调用AES加密函数 fill_number填充的位数 file_encrypted=open('file_encrypted','wb') # 生成存储加密后文件 file_encrypted.write(file_encrypted_msg) file_encrypted.close() printCN("原文件AES加密完成!") file_fill_number=open('fill_number','wb') # 生成存储填充位数文件 file_fill_number.write(str(fill_number)) file_fill_number.close() printCN("开始对原文件进行MD5摘要") md5_msg=md5_encrypt(file_msg) printCN("MD5摘要完成!") file.close() # 已不用原文件,关闭 file_rsa_private_name=raw_inputCN("请输入你的RSA私钥文件名:\n") printCN("开始对MD5摘要签名") signature_msg=rsa_private_encrypt(md5_msg,file_rsa_private_name) # MD5摘要RSA加密 printCN("MD5摘要签名完成!") printCN("对签名进行AES加密") # 因为MD5值是32位的,所以AES16位一块的加密不需要填充数据 signature_encrypted_msg,number=aes_encrypt(signature_msg,aes_key,iv) # number仅用来接收一个值,没有其他作用 file_signature_encrypted=open('file_signature_encrypted','wb') # 生成存储加密后的签名文件 file_signature_encrypted.write(signature_encrypted_msg) file_signature_encrypted.close() printCN("签名AES加密完成!") file_receiver_rsa_public_name=raw_inputCN("请输入接收者RSA公钥文件名:\n") printCN("开始对AES秘钥进行RSA加密") aes_key_encrypted=rsa_public_encrypt(aes_key,file_receiver_rsa_public_name) file_aes_key_encrypted=open('AES_key_encrypted','wb') file_aes_key_encrypted.write(aes_key_encrypted) file_aes_key_encrypted.close() printCN("AES秘钥RSA加密完成!") printCN("开始对iv进行RSA加密") iv_encrypted=rsa_public_encrypt(iv,file_receiver_rsa_public_name) file_iv_encrypted=open('file_iv_encrypted','wb') file_iv_encrypted.write(iv_encrypted) file_iv_encrypted.close() printCN("对iv的RSA加密完成!") file_aes_key.close() printCN("加密过程结束!") printCN("你需要发送给接收者的文件有:") printCN("1.已加密文件:file_encrypted") printCN("2.加密后的AES秘钥文件:AES_key_encrypted") printCN("3.AES加密后的初始化向量文件:file_iv_encrypted") printCN("4.加密后的签名文件:file_signature_encrypted") printCN("5.填充位数文件:fill_number") printCN("\n最后请删除程序所在路径下加入和生成的文件,谢谢!") raw_inputCN("回车结束程序\n") return def file_decrypt(): printCN("请把以下文件放在与此程序同一路径下:") printCN("1.加密的文件") printCN("2.加密的AES秘钥文件") printCN("3.加密的签名文件") printCN("4.加密的iv文件") printCN("5.你的RSA私钥文件") printCN("6.发送者的RSA公钥文件") printCN("7.填充位数文件") raw_inputCN("放好之后,回车继续\n") file_aes_key_encrypted_name=raw_inputCN("请输入加密的AES秘钥文件名:\n") iv_encrypted_name=raw_inputCN("请输入加密的AES初始化向量文件名:\n") file_rsa_private_key_name=raw_inputCN("请输入你的RSA私钥文件名:\n") file_aes_key_encrypted=open(file_aes_key_encrypted_name,'rb') aes_key_encrypted=file_aes_key_encrypted.read() file_iv_encrypted=open(iv_encrypted_name,'rb') iv_encrypted=file_iv_encrypted.read() printCN("开始解密AES秘钥") aes_key=rsa_private_decrypt(aes_key_encrypted, file_rsa_private_key_name) printCN("AES秘钥解密完成!") printCN("开始解密AES初始化向量") iv=rsa_private_decrypt(iv_encrypted,file_rsa_private_key_name) printCN("AES初始化向量解密完成!") file_encrypted_name=raw_inputCN("请输入加密的文件名:\n") file_encrypted=open(file_encrypted_name,'rb') file_encrypted_msg=file_encrypted.read() file_fill_number_name=raw_inputCN("请输入填充位数文件名:\n") file_fill_number=open(file_fill_number_name,'rb') fill_number=file_fill_number.read() printCN("开始对加密文件进行AES解密") file_msg=aes_decrypt(file_encrypted_msg,aes_key,iv) file_msg=file_msg[0:len(file_msg)-int(fill_number)] # 去掉AES加密时填充的位 printCN("加密文件AES解密完成!") file_fill_number.close() file_decrypted=open('file_decrypted','wb') # 解密内容输出到文件 file_decrypted.write(file_msg) md5_file_msg=md5_encrypt(file_msg) # 计算解密出来的文件的MD5值 file_decrypted.close() file_encrypted.close() # 加密文件解密完成,关闭 file_signature_encrypted_name=raw_inputCN("请输入加密的签名文件名:\n") file_signature_encrypted=open(file_signature_encrypted_name,'rb') signature_encrypted=file_signature_encrypted.read() printCN("加密签名文件AES解密") file_signature=aes_decrypt(signature_encrypted,aes_key,iv) printCN("加密签名文件AES解密完成!") file_signature_encrypted.close() file_aes_key_encrypted.close() # AES解密完成,关闭相关文件 file_iv_encrypted.close() sender_public_key_name=raw_inputCN("请输入发送者的公钥文件名:\n") printCN("开始签名文件RSA解密") md5_decrypted=rsa_public_decrypt(file_signature,sender_public_key_name) printCN("签名文件RSA解密完成,得到原文件MD5值!") if md5_file_msg==md5_decrypted: # MD5值校验 printCN("MD5值校验成功!") else: printCN("MD5值校验失败,请重新传输或检查错误原因") printCN("解密程序运行完毕,请提取解密文件,并删除此程序所在路径下导入及生成的文件,谢谢!") raw_inputCN("回车结束程序\n") return # AES加密 def aes_encrypt(aes_file, key,iv): # aes_file 文件,key 16-bytes 对称秘钥 from Crypto.Cipher import AES from Crypto import Random cipher = AES.new(key, AES.MODE_OFB,iv) # 生成了加密时需要的实际密码,这里采用OFB模式 # if fs is a multiple of 16 x = len(aes_file) % 16 printCN("要加密文件的长度是: %d"%len(aes_file)) printCN("需要填充的数据长度 : %d"%((16- x)%16)) if x != 0: aes_file_pad = aes_file + '0'*(16 - x) # It should be 16-x else: aes_file_pad=aes_file msg = cipher.encrypt(aes_file_pad) return msg,(16- x)%16 # AES解密 def aes_decrypt(aes_file, key,iv): from Crypto.Cipher import AES cipher = AES.new(key, AES.MODE_OFB,iv) # 生成了解密时需要的实际密码,这里采用OFB模式 msg=cipher.decrypt(aes_file) return msg # 计算MD5值 def md5_encrypt(md5_file): from Crypto.Hash import MD5 msg = MD5.new() msg.update(md5_file) return msg.hexdigest() # RSA私钥加密 def rsa_private_encrypt(msg,file_rsa_private_key_name): from M2Crypto import RSA # 用M2Crypto下的RSA模块 rsa_private_key=RSA.load_key(file_rsa_private_key_name) msg_encrypted=rsa_private_key.private_encrypt(msg,RSA.pkcs1_padding) return msg_encrypted # RSA公钥加密 def rsa_public_encrypt(msg,file_rsa_public_name): from M2Crypto import RSA # 用M2Crypto下的RSA模块 rsa_public_key=RSA.load_pub_key(file_rsa_public_name) msg_encrypted=rsa_public_key.public_encrypt(msg,RSA.pkcs1_padding) return msg_encrypted # RSA私钥解密 def rsa_private_decrypt(msg,file_rsa_private_key_name): from M2Crypto import RSA # 用M2Crypto下的RSA模块 rsa_private_key=RSA.load_key(file_rsa_private_key_name) msg_decrypted=rsa_private_key.private_decrypt(msg,RSA.pkcs1_padding) return msg_decrypted # RSA公钥解密 def rsa_public_decrypt(msg,file_rsa_public_name): from M2Crypto import RSA # 用M2Crypto下的RSA模块 rsa_public_key=RSA.load_pub_key(file_rsa_public_name) msg_decrypted=rsa_public_key.public_decrypt(msg,RSA.pkcs1_padding) return msg_decrypted
变量命名过长(没什么办法啊,组织能力不够)
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法