클라이언트와 서버간에 JSON 메시지를 암호화/해독하는 두 가지 방법이 있습니다. 서버에는 한 쌍의 RSA 키 (개인 키 하나와 공용 키)가 있으며 클라이언트도 마찬가지입니다. 또한 채널 자체가 안전하지 않기 때문에 JSON 메시지를 암호화하는 데 사용되는 통신을 처음 설정할 때 생성 된 대칭 세션 키에 액세스 할 수 있습니다. 클라이언트는 AES 키 (세션 키)를 생성 한 다음 서버의 공개 키 (모두에게 알려진)를 암호화한 다음이를 서버로 전송합니다. 서버는 세션 키를 해독하고 클라이언트 ID 아래의 HashMap
에 저장합니다.JAVA - 일치하지 않는 AES 키 길이
그러나 문제는 다음과 같습니다. 전송하기 전에 키 길이를 확인했으며 길이는 16 바이트입니다. 서버가 암호화 된 세션 키를 받고 해독하면 24 바이트 길이입니다. 암호문이나 암호 해독 중일 때 뭔가 잘못됐다고 가정합니다. 이것은 클라이언트가 요청을 (암호화 된 JSON 메시지의 형태로) 보내기를 시작하려고 할 때 키의 크기가 잘못 되었기 때문에 서버가 암호를 해독하고 읽을 수 없기 때문입니다 (java.security.InvalidKeyException
: Illegal key size 또는 기본 매개 변수).
사이퍼/방법은 아래에 게시되어 해독 :
encoder
/
decoder
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) {
(...)
}
}
는 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 + "\"}");
서버 암호화 된 세션 키를 받고 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"));
내가 시도 다른 알고리즘을 다른 패딩 ,하지만 오류가 어디 있는지 알 수는 없습니다.
이 : 또한, 같은뿐만 아니라 이진하기 위해
decipher(..)
을 변경을 동시에
byte[]
로 MSG를 허용하도록
cipher(..)
메도 변경이와 시도 확실하게 핵심 크기 문제를 해결했습니다. 이제 클라이언트 측과 서버 측 모두 16 바이트입니다. 감사합니다! 그'encoder.encodeToString (sk.getEncoded())'는 제가 시도한 이전 구현의 잔재였습니다. –