HYT MachineWorks

やったこととか思いついたことをメモしておくブログです。

Windows10 64bit + Miniconda 上でcondaからpycryptoのインストールにハマった件

pycryotoとは

指定した文字列を色々な暗号化アルゴリズムで暗号化できるパッケージpycrypto

pypi.org

conda でもpipを使わなくてもインストールできて

>conda install pycrypto

でインストールされたように見えます。でも、使えないのです。その解決法*1

 試しにサンプルコードを動かしてみると

今回使ったのは、PycryptoのPyPIに載っているAESのコードです。

from Crypto.Cipher import AES
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
message = "The answer is no"
ciphertext = obj.encrypt(message)
ciphertext
obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
obj2.decrypt(ciphertext)

 で、動かすと

>>> from Crypto.Cipher import DES3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "anaconda/mincondaのインストールフォルダ
from Crypto.Cipher import _AES
ImportError: cannot import name '_AES'

と怒ってきます。で、本当に無いのか

インストールファルダ/Lib/site-packeges/Crypto/Cipher/

もしくは、仮想環境だと

インストールファルダ/env/仮想環境名/Lib/site-packeges/Crypto/Cipher/

を開いてみると、こんな構成

Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2018/06/16 9:44 __pycache__
-a---- 2018/05/10 0:43 4126 AES.py
-a---- 2018/05/10 0:43 4953 ARC2.py
-a---- 2018/05/10 0:43 4385 ARC4.py
-a---- 2013/10/15 6:38 12596 blockalgo.py
-a---- 2018/05/10 0:43 4487 Blowfish.py
-a---- 2018/05/10 0:43 4527 CAST.py
-a---- 2018/05/10 0:43 4311 DES.py
-a---- 2018/05/10 0:43 5038 DES3.py
-a---- 2018/05/10 0:43 9592 PKCS1_OAEP.py
-a---- 2018/05/10 0:43 9335 PKCS1_v1_5.py
-a---- 2018/05/10 0:43 2822 XOR.py
-a---- 2018/05/10 0:44 31744 _AES.cp36-win32.pyd
-a---- 2018/05/10 0:44 18432 _ARC2.cp36-win32.pyd
-a---- 2018/05/10 0:44 11264 _ARC4.cp36-win32.pyd
-a---- 2018/05/10 0:44 22528 _Blowfish.cp36-win32.pyd
-a---- 2018/05/10 0:44 28672 _CAST.cp36-win32.pyd
-a---- 2018/05/10 0:44 58368 _DES.cp36-win32.pyd
-a---- 2018/05/10 0:44 58368 _DES3.cp36-win32.pyd
-a---- 2018/05/10 0:44 11264 _XOR.cp36-win32.pyd
-a---- 2012/05/24 21:55 3440 __init__.py

一応、_DESというファイルはありますが、ちょっと自分の環境と違います。

自分の環境

 python 3.6  OS windows 64bit

_DESファイル

 python 3.6 os windows 32bit

どうも、調べるとインストールされたビット数で確認をして実行しているみたいでした。

つまり、windows 64bitに32bitがインストールされている状態です。

色々試しましたが、一番カンタンなの解決法

以前のpycryotoの削除

conda uninstall pycrypto

チャンネル(パッケージのダウンロード先)を「conda-forge」に変更してインストール

conda install -c conda-forge pycrypto

-cはチャンネル変更のオプションです。

インストール後のCrypto/Cipher内は

Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2018/06/16 10:36 __pycache__
-a---- 2013/10/15 6:38 4218 AES.py
-a---- 2017/05/30 6:27 5046 ARC2.py
-a---- 2017/05/30 6:27 4385 ARC4.py
-a---- 2013/10/15 6:38 12596 blockalgo.py
-a---- 2017/05/30 6:27 4580 Blowfish.py
-a---- 2017/05/30 6:27 4620 CAST.py
-a---- 2013/10/15 6:38 4403 DES.py
-a---- 2013/10/15 6:38 5130 DES3.py
-a---- 2017/05/30 6:27 9592 PKCS1_OAEP.py
-a---- 2017/05/30 6:27 9335 PKCS1_v1_5.py
-a---- 2017/05/30 6:27 2822 XOR.py
-a---- 2017/05/30 6:27 35840 _AES.cp36-win_amd64.pyd
-a---- 2017/05/30 6:27 22016 _ARC2.cp36-win_amd64.pyd
-a---- 2017/05/30 6:27 14848 _ARC4.cp36-win_amd64.pyd
-a---- 2017/05/30 6:27 26624 _Blowfish.cp36-win_amd64.pyd
-a---- 2017/05/30 6:27 33280 _CAST.cp36-win_amd64.pyd
-a---- 2017/05/30 6:27 62464 _DES.cp36-win_amd64.pyd
-a---- 2017/05/30 6:27 61440 _DES3.cp36-win_amd64.pyd
-a---- 2017/05/30 6:27 14848 _XOR.cp36-win_amd64.pyd
-a---- 2012/05/24 21:55 3440 __init__.py

 となっていて、64bitになっています。

テストを動かすと、

>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
>>> message = "The answer is no"
>>> ciphertext = obj.encrypt(message)
>>> ciphertext
b'Öd!VTª`Aàñ'
>>> obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
>>> obj2.decrypt(ciphertext)
b'The answer is no'

 という感じで、動いているようです。

最後の復号化したときは、返り値はバイト型ということ。テキストで受け取りたいならば

>>> obj2.decrypt(ciphertext).decode()
'The answer is no'

 と、デコードして受け取るといいでしょう。

最後に注意を一つ

conda install python=3.5

とかやってダウングレードするとデフォルトのチャンネルから入れ直してくれるのでもう一度同じことをやらないと同じ現象が出ます。もう、一番目のチャンネルをconda-forgeにしようかな。

以上

*1:ちなみに、Anacondaの場合はじめからインストールされているから無関係と思う、多分、MinicondaやAnacondaで意図的に削除した場合の話