Qtでの単純なファイル暗号化および復号化の実装

ご挨拶、立派なhabrasociety。



最近、Qtプロジェクトでファイルを暗号化および復号化する必要に遭遇しました。 本質的に、 QFileを介したファイルの作業を、暗号化された形式でデータを書き込み、暗号化されたファイルから読み取ることができるものに置き換える必要があるため、主な条件はシンプルさと透明性です。 その結果、小さなクラスが生まれました。 それを一般の人と共有したいという願いがありました。誰かが便利になって時間を節約したり、誰かがそれを完成させてより良い生活を送るかもしれません。



私が言ったように、重要な点はクラスでのシンプルで透明な作品でした。 つまり このクラスは、暗号化された形式ですぐにデータを書き込むことができ、暗号化されたファイルから元のデータを読み取ることができる必要があります。



すでにQt、特にQIODeviceに精通している人は、入出力デバイスを操作するための強力なツールを知っています。 そのため、このクラスを基礎として継承することをほぼ即座に決定しました。 この点については詳しく説明しませんが、主な「魔法」はメソッドを再定義することだけです。

qint64 QIODevice::writeData(const char *data, qint64 len)
      
      



そして

 qint64 QIODevice::readData(char *data, qint64 len)
      
      



それぞれ、データの記録および読み取り用。



使用するファイルを指定するには、クラスユーザーにいくつかの方法があります。

1)ファイルパスを渡す

2)QFileDeviceオブジェクトにポインターを渡します。



QFileではなくQFileDeviceを使用する理由がわからない場合は、答えは簡単です。 そのため、 QSaveFileなどの便利なクラスを渡すことができます。



その後、質問が関連するようになりました。データを暗号化および復号化するために直接使用するツールはどれですか? 簡単な調査の後、OpenSSLライブラリで停止することが決定されました。これは、第一に、データ暗号化の世界のリーダーの1つであり、第二に、プロジェクトがすでにこのライブラリを他のタスクに使用しているためです。



したがって、暗号化アルゴリズムを選択するとき、対称アルゴリズムを使用することが決定されました。 データをブロック単位ですばやく暗号化できます。 実装されているクラスの重要な要件は、どこからでもファイルに書き込むことができることでした。 この点で、暗号化されたデータは以前のデータまたは後続のデータに依存していなかったことに留意する必要がありました。 すべての制限を考慮して、 ECBモードの AESアルゴリズムを選択することにしました(更新を参照)。 このモードでは、特定のデータブロックを他のブロックから独立させることができますが、もちろんセキュリティレベルは低下します。 私はこれを受け入れなければなりませんでした。 ユーザーが128、192、または256ビットのキービットサイズを選択できるようになったことは注目に値します(ビットサイズが小さいほどアルゴリズムの動作は速くなりますが、安全性は低下します)。 OpenSSLを使用した暗号化では、高レベルのEVP暗号化方法が使用されました



クラスの実装中に、ファイルを開くときの正確さを制御するために、暗号化されたファイルの特定のヘッダーを作成し、パスワードやソルトハッシュなどの必要なものを保存するというアイデアが浮上しました。 当然のことながら、いずれの場合でも、ユーザーは間違ったパスワードとソルトを使用してファイルを正常に読み取ることはできませんが、ファイルを開くときにそれを確認することを決定しました。これにより、ユーザーは、正しく暗号化されたファイルを開いた場合、正しいソースデータで作業できるようになりました。



興味深い点のうち、クラスが通常のファイルを処理できることは注目に値します。 パスワードを指定しない場合、通常のQFileで作業しているかのようにファイルで作業します。



クラスでの作業を理解するために、2つのテストプロジェクトを作成しました。

最初のプロジェクトには、基本的なファイル操作が含まれています。 比較のために、QFileクラスオブジェクトが使用され、その結果は開発されたクラスで確認されます。

2番目のプロジェクトは、エンドユーザーのために暗号化されたファイルを使用して作業を整理することがどのように役立つかを示しています。 プロジェクトは、ユーザーが選択した画像の暗号化と、QWebViewでのその後の表示を実装します-ファイルは暗号化されますが、ユーザーには元の画像が表示されます。



このクラスの使用は非常に簡単です。2つのファイル(cryptfiledevice.cppとcryptfiledevice.h)をプロジェクトにコピーすれば、既に作業できます。



現時点での依存関係:

1)Qt> = 5.1.0(SHA3がパスワードとソルトハッシュに使用されるため)

2)C ++ 11をサポートするコンパイラ



クラスおよびテストプロジェクトは、Windows 7(x86、x64)、Ubuntu(x64)、およびMacOS X Mavericksでテストされました。



将来、私が実現したいと思ういくつかの考えがまだあります。 これは、QFileに類似したremove、rename、existsメソッドの実装であり、QFileが不要な場合は含めないようにします。 また、このファイルが暗号化されているかどうかをユーザーが判断できるメソッドを追加したいと思います。 近い将来、手を差し伸べることを望み、この機能を追加します。

さらに、他のアルゴリズムの使用を検討することもできます。



MITライセンスの下で、GitHubのパブリックドメインにソースをアップロードしました。 健康を取り、使用し、改善します。 すべての提案や要望をメールで送信するか、課題トラッカーに書き込むことができます(すべての情報はGitHubのREADMEにあります)。



GitHubリンク: CryptFileDevice



更新する



気遣うすべての人のおかげで、私は提案や希望を伴う多くのフィードバックがあるとは思っていませんでした。

私は多数意見を考慮に入れようとしました。

AES-ECBをAES-CTRに変更し、暗号化セキュリティを強化しました( Disasmのおかげです )。

すべての修正はGitHubにアップロードされます



All Articles