MySQLのユーザー名とパスワードを逆コンパイルから保護するにはどうすればよいですか?
-
22-07-2019 - |
質問
Java .class
ファイルはかなり簡単に逆コンパイルできます。コードでログインデータを使用する必要がある場合、どうすればデータベースを保護できますか?
解決
パスワードをコードにハードコードしないでください。これは最近、トップ25の最も危険なプログラミングの間違い:
シークレットアカウントのハードコーディングと ソフトウェアへのパスワードは 非常に便利-熟練者向け リバースエンジニア。パスワードが すべてのソフトウェアで同じ、 その後、すべての顧客が脆弱になります そのパスワードが必然的になるとき 知られています。そして、ハードコーディングされているため、 修正するのは非常に苦痛です。
パスワードなどの構成情報は、アプリケーションの起動時に読み取る別のファイルに保存する必要があります。これが、逆コンパイルの結果としてパスワードが漏洩するのを防ぐ唯一の本当の方法です(最初からバイナリにコンパイルしないでください)。
このよくある間違いの詳細については、 CWE-259の記事をご覧ください。この記事には、より詳細な定義、例、および問題に関するその他の多くの情報が含まれています。
Javaでこれを行う最も簡単な方法の1つは、Preferencesクラスを使用することです。あらゆる種類のプログラム設定を保存するように設計されており、その一部にはユーザー名とパスワードを含めることができます。
import java.util.prefs.Preferences;
public class DemoApplication {
Preferences preferences =
Preferences.userNodeForPackage(DemoApplication.class);
public void setCredentials(String username, String password) {
preferences.put("db_username", username);
preferences.put("db_password", password);
}
public String getUsername() {
return preferences.get("db_username", null);
}
public String getPassword() {
return preferences.get("db_password", null);
}
// your code here
}
上記のコードでは、ユーザー名とパスワードを尋ねるダイアログを表示した後、 setCredentials
メソッドを呼び出すことができます。データベースに接続する必要がある場合は、 getUsername
および getPassword
メソッドを使用して、保存されている値を取得するだけです。ログイン資格情報はバイナリにハードコードされないため、逆コンパイルしてもセキュリティ上のリスクはありません。
重要な注意:設定ファイルはプレーンテキストXMLファイルです。許可されていないユーザーが未加工のファイル(UNIX許可、Windows許可など)を表示できないように、適切な手順を実行してください。 Linuxでは、少なくとも、これは問題ではありません。 Preferences.userNodeForPackage
を呼び出すと、現在のユーザーのホームディレクトリにXMLファイルが作成されるため、とにかく他のユーザーは読み取ることができません。 Windowsでは、状況が異なる場合があります。
その他の重要な注意事項:この回答や他の人のコメントには、この状況に対する正しいアーキテクチャとは何かについて多くの議論がありました。元の質問では、アプリケーションが使用されているコンテキストについては実際には言及されていないため、考えられる2つの状況について説明します。 1つ目は、プログラムを使用している人がデータベースの資格情報をすでに知っている(そして知ることが許可されている)場合です。 2番目は、開発者であるあなたがプログラムを使用している人からデータベース資格情報を秘密にしようとしている場合です。
最初のケース:ユーザーはデータベースログイン資格情報を知る権限があります
この場合、上で述べた解決策が機能します。 Java Preference
クラスはユーザー名とパスワードをプレーンテキストで保存しますが、設定ファイルは許可されたユーザーのみが読み取り可能です。ユーザーは単に設定XMLファイルを開いてログイン資格情報を読み取ることができますが、ユーザーは最初から資格情報を知っているため、セキュリティ上のリスクはありません。
2番目のケース:ユーザーに対してログイン認証情報を非表示にしようとしている
これはより複雑なケースです。ユーザーはログイン資格情報を知っている必要はありませんが、データベースにアクセスする必要があります。この場合、アプリケーションを実行しているユーザーはデータベースに直接アクセスできます。つまり、プログラムはログイン資格情報を事前に知る必要があります。上記のソリューションは、この場合には適切ではありません。データベースログイン資格情報を設定ファイルに保存できますが、ユーザーはそのファイルを読み取ることができます。
他のヒント
アプリケーションが読み取るファイルにパスワードを入力します。ソースファイルにパスワードを埋め込まないでください。期間。
Rubyには、 DBI :: DBRC というあまり知られていないモジュールがあります。 Javaに同等のものがあることは間違いありません。とにかく、それを書くことは難しくありません。
Webアプリケーションを作成していますか?その場合は、JNDIを使用してアプリケーションの外部で構成します。概要はこちらで入手できます。
JNDIは、 リモートを見つけてアクセスするためのアプリケーション ネットワークを介したサービス。リモート サービスはエンタープライズサービスである可能性があり、 メッセージングサービスまたは アプリケーション固有のサービス、ただし、 もちろん、JDBCアプリケーションは 主にデータベースに興味がある サービス。 DataSourceオブジェクトが JNDIで作成および登録 アプリケーションが使用できるネームサービス そのDataSourceにアクセスするためのJNDI API オブジェクトは、次に使用することができます データソースに接続します を表します。
何をしても、機密情報はどこかのファイルに保存されます。あなたの目標は、できるだけ入手するのを難しくすることです。これをどれだけ達成できるかは、プロジェクト、ニーズ、および会社の財布の厚さに依存します。
最良の方法は、パスワードをどこにも保存しないことです。これは、ハッシュ関数を使用してパスワードハッシュを生成および保存することで実現されます。
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366
ハッシュアルゴリズムは一方向の関数です。彼らはあらゆる量のデータを 固定長の「指紋」にそれを元に戻すことはできません。彼らもまた 入力が少しでも変化した場合、 結果のハッシュは完全に異なります(上記の例を参照)。この パスワードを保存したいので、パスワードを保護するのに最適です パスワードファイル自体が 侵害されましたが、同時に、 ユーザーのパスワードが正しい。
無関係なメモ: インターネットの昔、「パスワードを忘れた」リンクをクリックすると、ウェブサイトはプレーンテキストのパスワードをメールで送信していました。それらはおそらくデータベースのどこかにそれらを保存していたでしょう。ハッカーがデータベースにアクセスすると、すべてのパスワードにアクセスできます。多くのユーザーが複数のWebサイトで同じパスワードを使用するため、これは大きなセキュリティ上の問題でした。幸いなことに、最近ではこれは一般的な方法ではありません。
次は質問です。パスワードを保存する最良の方法は何ですか? これ(認証およびユーザー管理サービスストームパス)のソリューションは非常に気になります理想的なもの:
- ユーザーが資格情報を入力すると、これが検証されます パスワードハッシュ
- パスワードではなく、パスワードハッシュが生成および保存されます
- ハッシュは複数回実行されます
- ランダムに生成されたソルトを使用してハッシュが生成されます
- ハッシュは秘密鍵で暗号化されます
- 秘密鍵はハッシュとは物理的に異なる場所に保存されます
- 秘密鍵は時間ベースで更新されます
- 暗号化されたハッシュはチャンクに分割されます
- これらのチャンクは物理的に別々の場所に保存されます
明らかにあなたはグーグルや銀行ではないので、これはあなたにとって過剰な解決策です。しかし、次の質問があります。プロジェクトにどれだけのセキュリティが必要か、どれだけの時間とお金があるか?
多くのアプリケーションでは、推奨されていませんが、コードにハードコードされたパスワードを保存することで十分な解決策になるかもしれません。ただし、上記のリストからいくつかの追加のセキュリティ手順を簡単に追加することで、アプリケーションをより安全にすることができます。
たとえば、ステップ1がプロジェクトで受け入れられるソリューションではないと仮定します。ユーザーに毎回パスワードを入力させたくない、またはユーザーにパスワードを知らせたくない/必要ない。それでも、どこかに機密情報があり、これを保護する必要があります。単純なアプリケーションがあり、ファイルを保存するサーバーがないか、これがプロジェクトにとって面倒です。アプリケーションは、ファイルを安全に保存できない環境で実行されます。これは最悪のケースの1つですが、セキュリティ対策を追加することで、より安全なソリューションを実現できます。たとえば、機密情報をファイルに保存し、ファイルを暗号化できます。暗号化秘密鍵をコードにハードコーディングすることができます。コードを難読化できるため、誰かがそれを解読するのを少し難しくすることができます。この目的のために多くのライブラリが存在します。このリンクを参照してください。 (これは100%安全ではないことをもう一度警告したいと思います。正しい知識とツールを持つ賢いハッカーはこれをハッキングできます。しかし、
この質問は、パスワードやその他のデータを暗号化されたファイルに保存する方法を示しています。 Java 256ビットAESパスワードベースの暗号化
MD5は暗号化アルゴリズムではなく、ハッシュアルゴリズムです。要するに、ハッシュされたwat uを戻すことはできず、比較することしかできません。 データベースのユーザー名とパスワードではなく、ユーザー認証情報を保存するときに使用するのが理想的です。 データベースのユーザー名とパスワードは暗号化され、構成ファイルに保存される必要があります。