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

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

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

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

Python 3.x

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

132閲覧

C++) pythonで暗号化したファイルを復号する方法

kkjiji

総合スコア45

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

Python 3.x

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2025/04/18 11:08

編集2025/04/18 12:21

実現したいこと

PythonでPytorchを使って学習したモデルをonnxに変換するとき、pycryptdomeライブラリを使って暗号しました。
暗号したファイルをC++のOpenSSLライブラリを使って復号化してモデルをロードしたいのですが、うまく復号することができませんでした。復号したモデルはTensorRTでモデル変換した後、ロードする予定です。

◯python
暗号化ではpycryptdome==3.22.0を使って添付のコードのようにpytorchモデルをonnxモデルに変換しました。python側では問題なく復号化することはできました。

◯C++
OpenSSL==v3.4.1を使って添付のコードのように復号化する関数を作りました。

手探りで作ったものなので、python側の暗号化に問題があるのか・C++の復号側に問題があるのか・そもそもpythonで暗号化したものがC++で複合するのは難しいのかなど問題の特定ができていないです。
別の方法でも気密性・完全性が担保されるような方法であれば問題ないのでご享受ください。

発生している問題・分からないこと

C++の復号の関数(53行目)
EVP_CIPHER_CTX_ctr (ctx, EVP_CTRL_GCM_SET_TAG, tag.size(), tag.data()) != 1
がfalseのため、raiseでエラー終了します。

C++でOpenSSLを使ってEER_print_errors_fp(stderr);で出力すると以下のようなエラーが出ています。

エラーメッセージ

error

1OPENSSL_Uplink(00007FFAD83F6A28,08): no OPENSSL_Applink 2

該当のソースコード

Python

1import io 2import torch 3from Crypto.Cipher import AES 4from Crypto.Protocol.KDF import PBKDF2 5from Crypto.Random import get_random_bytes 6 7def export_onnx(self, onnx_model,dummy_input, output_model_path, export_params, opset_version, do_constant_folding, input_names, output_names, dynamic_axes, verbose) : 8 9 # メモリにONNXモデルをエクスポート 10 buffer = io.BytesIO) 11 torch.onnx.export (onnx_model, 12     dummy_ input, 13     buffer, 14     export_params=export_params, 15     opset_version=opset_version, 16     do_constant_folding=do_constant_folding, 17     input_names=input_names, 18     output_names=output_names, 19     dynamic_axes=dynamic_axes, 20     verbose=verbose) 21 onnx_model_binary = buffer getvalue() 22 23 pass = "abcdefg" 24 salt = get_random_bytes(16) 25 key = PBKDF2(pass, salt, dkLen=32, count=1000000) 26 cipher = AES.new (key, AES.MODE_GCM) 27 ciphertext, tag = cipher.encrypt_and_digest(onnx_model_binary) 28 # 暗号されたデータをファイルに保存 29 with open (output_model_path, 'wb') as f: 30 f.write(salt + cipher.nonce + tag + ciphertext)

C++

1#include <openssl/evp.h> 2#include <openssl/aes.h> 3#include <openssl/err.h> 4 5std::vector<chardecryptModel(char* modelpath, std::string pass) { 6 std:: ifstream file(modelpath, std:: ios: :binary): 7 if (!file) { 8 throw std::runtime_error ("Failed to open encrypted model file."); 9 } 10 11 //ファイルから復号化に必要なデータを取得 12 std::vector <unsigned char > salt (16); 13 std::vector<unsigned char> nonce (16); 14 std::vector<unsignedchar› tag (16); 15 16 file.read (reinterpret_cast<char*>(salt.data()), salt.size()); 17 file.read (reinterpret_cast<char*>(nonce.data()), nonce.size ()); 18 file.read (reinterpret_cast<char*>(tag.data()), tag.size()); 19 20 //暗号化されたモデルデータを取得 21 std::vector<unsigned charciphertext ((std:: istreambuf_iterator<char(file)), std::istreambuf_iterator<char()); 22 file.close(); 23 24 //PBKDF2を使用してキーを取得 25 std::vector<unsigned char> key (32) ; 26 if (IPKCS5 PBKDF2_ HMAC(pass.c_str(), pass.size(), salt.data(), salt.size(), 1000000, 27 EVP_sha256(), key-size(), key .data())){ 28 throw std::runtime_error ("Failed to derive key using PBKDF2."); 29 } 30 31 // 復号化コンテキスト初期化 32 EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); 33 if (!ctx) { 34 throw std::runtime error ("Failed to create EVP_CIPHER_СTX."); 35 } 36 37 if (EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), (), nullptr, nullptr, nullptr) != 1 || 38 EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, nonce.size(), nullptr) != 1 || 39 EVP_DecryptInit_ex(ctx, nullptr, nullptr, key.data(), nonce.data()) != 1){ 40 41 EVP_CIPHER _CTX_free (ctx) ; 42 throw std::runtime error ("Failed to initialize decrypt ion."); 43} 44 45 // モデルデータを復号化 46 std::vector<unsigned chardecrypted (ciphertext.size)); 47 int len = 0; 48 if (EVP DecryptUpdate(ctx, decrypted.data(), &len, ciphertext.data(), ciphertext.size ()) != 1) 49 { 50 EVP_CIPHER_CTX_free (ctx); 51 throw std::runtime error ("Decrypt ion failed."); 52 } 53 54 int decryptedLen = len; 55 if (EVP_CIPHER_CTX_ctr (ctx, EVP_CTRL_GCM_SET_TAG, tag.size(), tag.data()) != 1 || 56 EVP_DecryptFinal_ex(ctx, decrypted.data() + len, &len) != 1) { 57 58 EVP_CIPHER_CTX_free (ctx); 59 throw std::runtime_error ("Decryption failed."); 60 } 61 62 decryptedLen += len; 63 decrypted.resize (decryptedLen) : 64 EVP_CIPHER_CTX_free (ctx); 65 66 //復号化されたデータからモデル情報を取得 67 std::vector<charmode_Data(decrypted.begin(), decrypted.end ()); 68 return modelData; 69}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Google等で調べながら作ったコードで何が問題なのか自体が特定できていません。

補足

特になし

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

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

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

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

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

guest

回答1

0

自己解決

pythonのPBKDF2でhmac_hash_module=SHA256を引数にセットすればいけました。

投稿2025/04/18 13:51

kkjiji

総合スコア45

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問