クライアント/サーバー インフラストラクチャを使用してアプリケーションを構築しており、公開/秘密キー方式を使用して認証メカニズムを実装したいと考えています。
クライアントが秘密鍵を所有し、サーバーが公開鍵しか持っていないと仮定しましょう。認証中、クライアントは秘密鍵でメッセージに署名し、公開鍵で検証されるサーバーに送信します。検証が成功すると、クライアントは認証されます。
以下は、概念に慣れた JUnit テスト コードです。
@Test
public void testSignature() throws Exception {
final String message = "Hello world is a stupid message to be signed";
final KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
final Signature privSig = Signature.getInstance("SHA1withRSA");
privSig.initSign(keyPair.getPrivate());
privSig.update(message.getBytes());
byte[] signature = privSig.sign();
final Signature pubSig = Signature.getInstance("SHA1withRSA");
pubSig.initVerify(keyPair.getPublic());
pubSig.update(message.getBytes());
assertTrue(pubSig.verify(signature));
}
もちろん、これが機能するためには、サーバーとクライアントの両方がプレーン メッセージ (ダイジェスト) を所有している必要があります。
ここで私の質問は次のとおりです。署名に使用するのに適したメッセージ (ダイジェスト) は何ですか? たとえば、これは静的なハードコードされた文字列 (すべてのクライアントに使用される) である可能性がありますか?それとも、この概念に何らかのセキュリティ上の問題を課すことになるでしょうか? 静的な文字列が悪い場合、認証の前にランダムな文字列をネゴシエートするのは良い考えでしょうか? このランダムな文字列は、たとえば「セッション」キーとして使用でき、しばらくすると無効になります。