クライアントとサーバーの間でJSONメッセージを暗号化/解読する2つの方法があります。サーバーにはRSAキー(プライベートとパブリック)のペアがあり、クライアントも同様です。さらに、チャネル自体が安全でないため、JSONメッセージを暗号化するために使用される通信を最初に確立したときに生成された対称セッション鍵にアクセスできます。クライアントはAES鍵(セッション鍵)を生成し、サーバの公開鍵(すべてに知られている)と暗号化し、サーバに送信します。サーバは、セッション鍵を解読し、クライアントのIDのHashMap
に格納します。JAVA - 一致しないAESキーの長さ
これは問題ですが、送信する前に鍵の長さを確認していますが、長さは16バイトです。サーバーが暗号化されたセッションキーを受信し、それを解読すると、サーバーは24バイトの長さになります。私は何か間違っている間、暗号または解読操作中に間違っていたと仮定します。これは、クライアントが要求を(暗号化されたJSONメッセージの形で)送信を開始したいときに、キーのサイズが間違っているためにサーバーが解読して読み取ることができないためです(java.security.InvalidKeyException
:Illegal key sizeまたはデフォルトパラメータ)。
暗号/解読方法を以下に掲載されています
public String cipher(Key key, String alg, String msg){
try {
Cipher c = Cipher.getInstance(alg);
c.init(Cipher.ENCRYPT_MODE, key);
return encoder.encodeToString(c.doFinal(msg.getBytes("UTF-8")));
} catch (IllegalBlockSizeException e) {
(...)
}
}
encoder
/decoder
がjava.util.Base64
からです。
public String decipher(Key key, String alg, String msg){
try {
Cipher c = Cipher.getInstance(alg);
c.init(Cipher.DECRYPT_MODE,key);
return new String(c.doFinal(decoder.decode(msg)), "UTF-8");
} catch (IllegalBlockSizeException e) {
(...)
}
}
クライアントの暗号化セッション鍵送信:
SecretKey sk = KeyGenerator.getInstance("AES/CBC/PKCS5Padding").generateKey();
System.out.println(sk.getEncoded().length) //length = 16 bytes
String sessionKey = cipher(client.getServerPublicKey(),
"RSA/ECB/PKCS5Padding", encoder.encodeToString(sk.getEncoded()));
printWriter.write("{(...), \"key\":\"" + sessionKey + "\"}");
Serverの暗号化セッション鍵を受信し、HashMap
でそれを保存:
byte[] aux = decipher(registry.getServerPrivateKey(),
"RSA/ECB/PKCS5Padding", data.get("key").toString().replace("\"", ""))
.getBytes("UTF-8");
System.out.println(aux.length) //length = 24 bytes
registry.addSession(..., new SecretKeySpec(aux, 0, aux.length, "AES"));
を私は異なるアルゴリズムと異なるパディングを試してみましたしかし、私はエラーがどこにあるのかわからない。
この本を試してみてください確かにキーサイズの問題を解決しました。クライアント側とサーバー側の両方で16バイトになりました。ありがとうございます!その 'encoder.encodeToString(sk.getEncoded())'は私が試した以前の実装の残り物でした。 –