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

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

新規登録して質問してみよう
ただいま回答率
85.53%
OpenSSL

OpenSSLはSSL/TLSのプロトコルと一般的な暗号のライブラリを導入するオープンソースのソフトウェアのツールキットです。

Python

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

Q&A

1回答

284閲覧

pythonコードでopensslコマンドと同等の暗号化をしたい

828kk88

総合スコア61

OpenSSL

OpenSSLはSSL/TLSのプロトコルと一般的な暗号のライブラリを導入するオープンソースのソフトウェアのツールキットです。

Python

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

0グッド

0クリップ

投稿2023/11/21 06:49

編集2023/11/21 23:35

openssl enc -e aes-256-cbc -base64 -iv iv値 -k 暗号鍵 ファイル -in 暗号化前ファイル名 -out 暗号化後ファイル名 -md sha256

上記コマンドと同等のpythonコードを書きたいです

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding from cryptography.hazmat.backends import default_backend from base64 import b64encode def test_enc(): # IVとキーを16進数からバイトに変換 iv = bytes.fromhex(iv値) key = hashlib.sha256(bytes.fromhex(キー)) # ファイルを読み込む with open('before_encrypt.csv', 'rb') as f: data = f.read() # パディング処理 padder = padding.PKCS7(128).padder() padder_data = padder.update(data) + padder.finalize() cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() # データを暗号化 encrypted_data = encryptor.update(padder_data) + encryptor.finalize() # 暗号化されたデータをBase64エンコードしてファイルに書き込む with open('encrypted.csv', 'wb') as f: f.write(b64encode(encrypted_data))

ライブラリ変えたパターン

from Crypto.Cipher import AES from base64 import b64encode import hashlib def test_enc(): # IVとキーをバイトに変換 iv = bytes.fromhex(iv値) key = hashlib.sha256(キー.encode()).digest() # ファイルの読み込み with open('before_encrypt.csv', 'rb') as f: data = f.read() # パディング処理 padder = padding.PKCS7(128).padder() padder_data = padder.update(data) + padder.finalize() cipher = AES.new(key, AES.MODE_CBC, iv) # データを暗号化 encrypted_data = cipher.encrypt(padder_data) # 暗号化されたデータをBase64エンコードしてファイルに書き込む with open('encrypted.csv', 'wb') as f: f.write(b64encode(encrypted_data))

このようなコードを書いているのですが、暗号化後のファイルの中身がopensslコマンドを実行する場合と全く異なるものになります。

例えばaaaaaaaaaとだけ書いた適当なファイルを暗号化してみた結果
openssl暗号化→U2FsdGVkX19p4HtziF4MIqmV58VE9860Tc1oyQ2x+oI=
コードによる暗号化→OgSvtBFb7lqtEJYWzcpUJA==

のようになります

-kオプションと-md sha256によるキーの変換が再現できていないように思われるのですが、なにかお気づきの方がいれば教えていただきたいです。

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

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

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

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

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

ikedas

2023/11/21 07:54

どのように「暗号化後のファイルの中身がopensslコマンドを実行する場合と全く異なるものにな」るのか具体的に記してください。 このコメント欄に書くのではないです。質問文を編集して書いてください。
can110

2023/11/21 08:55

第三者が現象を再現できるような内容に質問を修正すると、もしかしたら回答が得られるかもしれません(得られないかもしれません)
melian

2023/11/21 11:26 編集

OpenSSL は salt を付けますが、cryptography は付けません。なので、openssl コマンドで暗号化する際に -nosalt オプションを付けると内容が同じになります。 openssl aes-256-cbc -e -base64 -nosalt -iv iv値 -k パスワード -in before_encrypt.csv -md sha256 それと、openssl コマンドの場合は message digest の最後に改行コード(0x0a)を付けます。改行コードがない場合、openssl コマンドによる復号の際にエラーが発生します。(bad decrypt) その場合は、-A オプションを付けます。 なお、-k 暗号鍵 と指定されていますが、小文字 k オプションは暗号鍵ではなくパスワードを指定するものです。 -k password   The password to derive the key from. This is for compatibility with previous versions of OpenSSL. Superseded by the -pass argument. なので、 key = hashlib.sha256(bytes.fromhex(キー)) を、 key = hashlib.sha256(パスワード.encode()).digest() に変更する必要があります。
guest

回答1

0

openssl コマンドによる暗号化

bash

1$ cat before_encrypt.csv 2aaaaaaaaa 3 4# encrypt 5$ openssl aes-256-cbc -e -base64 -iv E4E45516708E9491C8C8320FF2678F98 -k mypassword -in before_encrypt.csv -out encrypted_by_openssl.csv -md sha256 6$ cat encrypted_by_openssl.csv 7U2FsdGVkX18686yTZxIylhemWNePiAfViBzq7I4uE0s= 8 9# extract salt, key and iv 10$ openssl aes-256-cbc -d -base64 -iv E4E45516708E9491C8C8320FF2678F98 -k mypassword -in encrypted_by_openssl.csv -P 11salt=3AF3AC9367123296 12key=44CB6B070AF3ED5C52EFD1CC666F2B75EEA93F8E62EC2447D0F97F94E52C04B1 13iv =E4E45516708E9491C8C8320FF2678F98

encrypt_with_aes-256-cbc.py

python

1from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 2from cryptography.hazmat.primitives import padding 3from cryptography.hazmat.backends import default_backend 4from base64 import b64encode 5import hashlib 6 7def test_enc(input_file, output_file, password, iv, salt): 8 # パスワードとIVをセットアップ 9 salt = bytes.fromhex(salt) 10 password = hashlib.sha256(password.encode() + salt).digest() 11 iv = bytes.fromhex(iv) 12 13 # ファイルを読み込む 14 with open(input_file, 'rb') as f: 15 data = f.read() 16 17 # パディング処理 18 padder = padding.PKCS7(algorithms.AES.block_size).padder() 19 padder_data = padder.update(data) + padder.finalize() 20 21 cipher = Cipher(algorithms.AES(password), modes.CBC(iv), backend=default_backend()) 22 encryptor = cipher.encryptor() 23 24 # データを暗号化 25 encrypted_data = encryptor.update(padder_data) + encryptor.finalize() 26 encrypted_data = b'Salted__' + salt + encrypted_data 27 28 # 暗号化されたデータをBase64エンコードしてファイルに書き込む 29 with open(output_file, 'wb') as f: 30 f.write(b64encode(encrypted_data) + b'\n') 31 32if __name__ == '__main__': 33 password = 'mypassword' 34 iv = 'E4E45516708E9491C8C8320FF2678F98' 35 salt = '3AF3AC9367123296' 36 input_file = 'before_encrypt.csv' 37 output_file = 'encrypted_by_crypto.csv' 38 test_enc(input_file, output_file, password, iv, salt)

Python スクリプトの実行結果と openssl コマンドによる暗号化データとの比較

bash

1$ python3 encrypt_with_aes-256-cbc.py 2$ cat encrypted_by_crypto.csv 3U2FsdGVkX18686yTZxIylhemWNePiAfViBzq7I4uE0s= 4 5$ diff encrypted_by_openssl.csv encrypted_by_crypto.csv 6$ echo $? 70 8# 一致

投稿2023/11/21 14:35

melian

総合スコア19490

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.53%

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

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

質問する

関連した質問