7

サーバー側から転送された公開鍵を使用して、クライアント側でセッション鍵を暗号化するにはどうすればよいですか?

またはを使用する必要がありますCipher.WRAP_MODECipher.ENCRYPT_MODE

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.WRAP_MODE, publicKey);
byte[] wrappedSessionKey = cipher.wrap(sessionKey);

encrypt_mode を使用して sessionKey を暗号化する方法がよくわかりません。誰かがこれについて私を助けることができますか?

4

1 に答える 1

32

ラッピングと暗号化は非常に似ていますが、ラッピングは何をしようとしているのかをより正確に表現します。一般的な「暗号化」は、セマンティックな意味を持たない生データを操作しますが、ラッピングはキーに関連することが知られています。したがって、このCipher.unwrap()メソッドはKey非バイト配列を返します。

キーのラッピングに wrap を使用すると、コードの移植性が向上します (特にハードウェア セキュリティ モジュールに関して)。状況によっては、キーのアクセス許可によってラッピング操作は許可されますが、キー バイトの生の暗号化は許可されません。

もちろん、JCE アーキテクチャ全体がプロバイダーの概念に基づいているため、目的の出力形式を取得するために、選択したプロバイダーに指定するアルゴリズムを正確に確認する必要があります。これは、ラップされた鍵データをサードパーティに送信する場合に特に重要です。


あなたの特定のケースでは、以下に示すように、 と の両方で同じ動作が示されWRAPENCRYPT結果を交換します。

KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "SunJSSE");
generator.initialize(2048);
KeyPair keyPair = generator.generateKeyPair();

SecretKey sessionKey = new SecretKeySpec(new byte[16], "AES");

Cipher c = Cipher.getInstance("RSA", "SunJCE");
c.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
byte[] result1 = c.doFinal(sessionKey.getEncoded());

c.init(Cipher.WRAP_MODE, keyPair.getPublic());
byte[] result2 = c.wrap(sessionKey);

c.init(Cipher.UNWRAP_MODE, keyPair.getPrivate());
SecretKey sessionKey1 = (SecretKey) c.unwrap(result1, "AES",
    Cipher.SECRET_KEY);

c.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
SecretKey sessionKey2 = new SecretKeySpec(c.doFinal(result2), "AES");

System.out.println(Arrays.equals(sessionKey1.getEncoded(),
    sessionKey2.getEncoded()));

これは以下を出力します:true

于 2013-05-16T12:04:01.473 に答える