🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

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

Q&A

解決済

1回答

1439閲覧

Cryptoppでクラッシュする

BeatStar

総合スコア4962

C++

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

0グッド

0クリップ

投稿2019/10/29 02:34

編集2019/10/29 03:21

お知恵をお貸しください。お願いします。

追記: ソースコードを下に開示いたします。

[概要] 該当のソースコードを使うと例外が飛んでくる. この例外をどうにかしたい.

現在、CryptoPPを使って、暗号化・復号をしようとしています。
しかし、上記のソースコードでは、復号の部分で、

"StreamTransformationFilter: ciphertext length is not a multiple of block size" (CryptoPP::InvalidCiphertext)

という例外が飛んできているようです。

documenationで、(私なりに)色々調べた結果、(TrippleDESの)復号時に例外
(上記のメッセージ付き)が飛んできているようです。

ただ、これ以上の知識がないため、どうやって対処すればいいのかがわかりません。

メッセージ的には「暗号文の長さがブロックサイズに合わない」系であることはわかりますが...
(長さはどのぐらいがベストなのかが不明瞭...)

どうやら decryptor->decrypt(...) 辺りで例外が飛んできているようです。

ここまではなんとかわかりましたが、
その解決策が思い浮かびません。

CryptoPP::Exceptionが持つメンバの中にGetErrorTypeメンバ関数があったので、
それで覗くと CryptoPP::Exception::INVALID_DATA_FORMAT のようです。

documentationを読むと

Input data was received that did not conform to expected format.
(= フォーマットに適合できない入力データを受け取った )

とあります。

もしかして「暗号化したりする対象データ群」がブロックサイズより大きいとできないのかなぁ。
と思い、

1. (バイナリモードで)1バイト分読み込む 2. 1で読み込んだcharデータを文字列としてencryptor->encrypt() に渡して暗号化 3. 2で取得した文字列を別のファイルに書き込む

みたいな感じにしてみました。

しかし、その場合はそもそもファイルサイズが大きいため、
(試したところ1時間経っても終わりそうにない...)
実用的ではないなぁと。

そのため、読み込むバイト数を1バイトから100バイトに変えてみても、
今回の最初のメッセージになります。

できればファイルを暗号化したいのですが...

[情報]
言語: C++
ライブラリ: cryptopp 8.3
OS: Windows 10
コンパイラ: MinGW (g++ (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0)
デバッガ: GDB


[追記1]

ご指摘があったので、zipファイルではなく、ここで開示します。
(そのため、Cryptoppは別途、ご用意してください。)

main.cpp: 字数制限のため、Pastebinに記述しています。

Basis.h: 字数制限のため、Pastebinに記述しています。

// お読みください.txt [注意] Cryptoppを(コンパイルした状態で)そのまま同梱していますが, 質問のためなのでご容赦を. [Problems] sample1.exeを起動すると"StreamTransformationFilter: ciphertext length is not a multiple of block size" というメッセージが出てクラッシュする. ただし, original.mp4 は適当なMP4ファイルとしている. [ソースの概要] Cryptoppを独自のDLLにして、例えば myencrytion.dll等のようにして、DLL内にあるクラスオブジェクトを使う 方式でやろうとしています。 なのでデザインパターンのFactoryパターン...でいいのでしょうか。一旦 CryptionManagerというクラスオブジェクトを生成し、 これが FactoryMethodパターン...?適用で、Ecryptorとかそういうのを生成する... という状態にしようとしています。 ただ、まずは実行ファイルすら作れないならDLLは作れないので、実行ファイルとして書いています。 [Compile] Cryptoppをmain.cppと同じディレクトリに置いた状態で、 以下のようにした. ( -lole32 とかはこのコードでは使っていないですが、後から使う可能性があるので付与しているとします... ) $ g++ -g -o sample1.exe main.cpp -I./cryptopp/include -L./cryptopp/lib -lcryptopp -lshlwapi -lwinmm -lole32 -lshell32 -luuid -lgdi32 -lurlmon -static-libgcc -static-libstdc++ -static -lpthread -DUNICODE

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

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

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

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

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

t_obara

2019/10/29 02:41

いきなりzipファイルダウンロードとか気持ちが悪いので、必要最小限の再現コードを質問欄に```で囲ってご提示ください。
BeatStar

2019/10/29 03:08

すみません。追記します。
guest

回答1

0

ベストアンサー

"StreamTransformationFilter: ciphertext length is not a multiple of block size" (CryptoPP::InvalidCiphertext)

ソースコードは読んでいませんが、TripleDESのブロック長は8バイトなので8の整数倍バイトずつデータを入力してください。

投稿2019/10/29 04:52

編集2019/10/29 04:54
SHOMI

総合スコア4079

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

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

BeatStar

2019/10/29 05:42 編集

ご回答ありがとうございます。 あ、なるほど。 (対象データが)8の倍数になっていればいいのか... これって、暗号化・復号ともに 8の整数倍バイトずつになるのでしょうか? 例えば、暗号化はそのままだけど、復号は 8の整数倍バイトずつみたいなパターンでしょうか? 現在、外出先からなので帰宅後試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問