質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

5532閲覧

暗号化処理で復号の時に、ファイルから読み込んだ文字列だと複合化に失敗する。UnicodeDecodeError: 'utf-8' codec can't decode

Aki1000

総合スコア78

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/12/22 07:11

あちこちから写経しつつpycryptodomeのcryptoを使って暗号化複合化処理をするコードを書きました。
(開発が終わってしまったpycryptoがインストール出来ないマシンがありpycryptodomeにアップデートせざるを得なかったので……。Simple-AES-Cipherはpycryptodomeだとうまく動かないのでそれっぽいのを作ろうかと。Simple-AES-Cipher がpycryptodomeで動けば良かったのですが)

python

1#Cipher.py 2from Crypto.Cipher import AES 3from Crypto import Random 4import base64 5 6 7class Cipher: 8 """注意・暗号化するテキストの末尾にスペースがあるとそのスペースは削除される""" 9 def __init__(self): 10 # iv = "L3f4mlTJtCIPV9af".encode('utf-8') # 初期化ベクトル(16文字で適当な値を設定) 11 n = 16 12 self.iv = bytes(Random.get_random_bytes(n)) 13 self.mode = AES.MODE_CBC # 暗号化モードを指定 14 15 def mkpad(self, s, size): 16 size=48 17 s = s.encode("utf-8") # UTF-8文字列をバイト列に変換する 18 pad = b' ' * (size - len(s) % size) # 特定の長さの倍数にするための空白を生成 19 return s + pad 20 21 # 暗号化する 22 def encrypt(self, password, data): 23 # 特定の長さに調節する 24 password = self.mkpad(password, 16) # 16の倍数にそろえる 25 data = self.mkpad(data, 16) # バイト列に変換し16の倍数に揃える 26 password = password[:16] # ちょうど16文字に揃える 27 28 # 暗号化 29 aes = AES.new(password, self.mode, self.iv) 30 data_cipher = aes.encrypt(data) 31 return base64.b64encode(data_cipher).decode("utf-8") 32 33 # 複合化する 34 35 def decrypt(self, password, encdata): 36 # パスワードの文字数を調整 37 password = self.mkpad(password, 16) # 16の倍数に揃える 38 password = password[:16] # ちょうど16文字に揃える 39 40 # 複合化 41 aes = AES.new(password, self.mode, self.iv) 42 encdata = base64.b64decode(encdata) # 暗号化データをBASE64でデコードしてバイト列に 43 data = aes.decrypt(encdata) # 複合化 44 data = data.strip() 45 return data.decode("utf-8")

これを使うために、下のようにすると問題なく動きます。しかしながら、

python

1#ciphertest0 2from module import Cipher 3Cipher = Cipher() 4 5with open(r"x:\xxxxx\xxx\AEKey.txt", 'r', encoding='utf-8') as file: 6 temp0 = file.read() 7 8message = "testtext" 9password = temp0 10# 暗号化する 11enc = Cipher.encrypt(password, message) 12 13# 複合化する 14dec = Cipher.decrypt(password, enc) 15 16print(enc) 17print(dec) 18 19if message == dec: 20 print("一致確認")

このencという暗号化されたテキストをファイルに保存し、同じように下に書いたコードでデコードしようとすると、
Traceback (most recent call last):
File "ciphertest1.py", line 20, in <module>
dec = Cipher.decrypt(password, temp1)
File "Cipher.py", line 49, in decrypt
return data.decode("utf-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 1: invalid continuation byte

言われてしまいます。utf-8で許されない文字列がある?
上のコードでencをtype(enc)とやって調べるとclass 'str'と出るのでただの文字列だと思うんですが、上のコードは問題なく通るのに下のコードは通りません。

エラーが出る復号化コードは以下の通りです。

python

1#ciphertest1 2from module import Cipher 3 4Cipher = Cipher() 5 6with open(r"x:\xxxxx\xxx\AEKey.txt", 'r', encoding='utf-8') as file: 7 temp0 = file.read() 8with open(r"x:\xxx\xxx\messagetext.txt", 'r', encoding='utf-8') as file: 9 temp1 = file.read() 10 11message = temp1 12password = temp0 13 14# 復号化する 15dec = Cipher.decrypt(password, temp1) 16print(dec) 17

試しに、messagetext.txtをファイルからの読み込みではなく、上のプログラム中で
dec = Cipher.decrypt(password, "g4Dj/kZ6z4w4Ia/ApBrw7OeBEHjB7k95XM1eNP6jXSGzcN/IiSITsVndLfvtv2Ks")

とやっても、同じです。
なぜ、上のciphertest0は問題なく動いて、下のciphertest1が動かないのかわかりません。
どうやったら動くようになるでしょう?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/12/22 10:49

Windows環境でutf-8のBOMが関係していないでしょうか?encoding='ISO-8859-1'としてみませんか?
Aki1000

2018/12/23 16:06

ISO-8859-1 プログラム中、全ての'utf-8'を'ISO-8859-1'と置き換えました。 すると、エラーで止まるのはなくなりました。 しかし、 enc = Cipher.encrypt(password, message) print(enc) で出てきた文字列を dec1 = Cipher.decrypt(password, "4wsAr0TO4NIxvXATkgWmLLEYKzwdy2bkpIRaUusGgnQ53MuWt8Ko77kM26xzHIRm") として複合化しても、 úåK_àÑÆÐmT4"  という文字列が出てくる。……復号化に失敗してしまいました……
argparse

2020/12/13 16:02

暗号化時と復号時に同じ iv を用いていないのが原因のように思われます。
guest

回答2

0

自己解決

解決済みにしないで放っておくのもなんなんで。

結局、この自作コードは使えなかったので、Crypto.Cipherを使った暗号化コードをネットで公開している人のところで写経して使いました。

投稿2020/12/13 15:46

Aki1000

総合スコア78

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

とりあえず、ここだけ

utf-8で許されない文字列がある?

0xC3 の次のバイトは、0x80 - 0xBF のバイトのみとなります。
Wikipedia (UTF-8)

その他はまだ見てません。

投稿2018/12/22 08:57

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問