中央サーバーからのコマンドをポーリングする分散アプリケーションがあり、それらのコマンドの内容は、各リモート サイトでアプリケーションと共に展開された公開鍵を使用して、秘密鍵によって「署名」されます。各コマンドは秘密鍵で署名され、その署名はコマンドが実行される前に検証されます。
Java で公開鍵と秘密鍵のペアを生成する方法を次に示します。(私は、1024 よりも多くのことを行う必要があることを認識しています)
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();
新しい要件は、単純な比較的安全なコマンドを送信することに加えて、ソフトウェアにインストーラーをダウンロードして実行し、それ自体を更新するように指示するコマンドを送信することです。これは、正しく行わないと大きな穴が開く可能性があります。「更新インストーラーの実行」コマンドは、通常どおり署名され、ダウンロードして実行される実行可能ファイルの md5 も含まれます。そのため、コマンドの署名は正しく (md5 を含む) 必要があり、ダウンロードしたファイルで計算された md5 は、実行前に正しい必要があります。これは、私が考えることができるほとんどの攻撃ベクトルを処理するはずです. 他に気をつけなければならないことはありますか?
そのため、これらのコマンドが発信されたサーバーで秘密鍵を保護することに注意を向けています。その秘密鍵を入手するとゲームオーバーです。そのキーをディスク上でどのように保護すればよいですか?
私の考えは、パスフレーズを使用した対称暗号化を使用して、その秘密鍵を保護することです。
私の現在の解決策は次のとおりです。
char[] passphrase; // Actual passphrase
PrivateKey privateKeyObj; // Actual Private Key
byte[] privateKeyBytes = privateKeyObj.getEncoded();
byte[] salt = new byte[8];
new SecureRandom().nextBytes(salt);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase, salt, 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal(privateKeyBytes);
FileOutputStream outputFileStream = new FileOutputStream(outputFile);
outputFileStream.write(salt);
outputFileStream.write(iv);
outputFileStream.write(ciphertext);
outputFileStream.close();
(明確にするために例外を削除しました)
これは基本的にソルトをランダムに生成し、パスフレーズを使用してキーを作成し、結果のソルト、IV、および暗号テキストを復号化の準備が整ったファイルに保存します。
しかし、私はここに何かが欠けていると感じています。有効な説明を取得できるように、キーに何らかのタイプの MAC を含める必要がありますか? たぶん、秘密鍵の前に既知のテキストを 5 バイトまたは 6 バイト置くだけの簡単な方法でしょうか? 現在、パスフレーズが正しくない場合、パディング例外が発生するだけですが、常にそうであるとは限らず、一部のパスフレーズがデコードされてジャンクになる可能性があることを読みました。これを防ぐ必要があると感じています。
私がここで正しい軌道に乗っているかどうかを誰かに知らせて、フィードバックを提供してもらえますか。これを可能な限り安全にすることが重要です..