Я работаю над некоторым программным обеспечением Java, которое влечет за собой шифрование и дешифрование информации на обоих концах сетевого подключения с использованием двух отдельных частей программного обеспечения. Чтобы облегчить это, у меня есть один класс, Cryptographer, который занимается шифрованием данных. На данный момент Controller (одна сторона соединения) и Agent (другая сторона) оба используют этот класс для генерации SecretKey на основе пароля, совместно используемого двумя программами.
Ключ генерируется в этой функции класса Cryptographer:
public SecretKey generateKey(String key) {
this._paramSpec = new PBEParameterSpec(this.SALT, this.ITERATION_COUNT);
PBEKeySpec spec = new PBEKeySpec(key.toCharArray());
SecretKeyFactory fac = null;
try {
fac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
System.err.println("[ERR] Cryptographer could not create a SecretKeyFactory due to an unsupported algorithm.");
}
try {
if (fac == null)
return null;
return fac.generateSecret(spec);
} catch (InvalidKeySpecException ex) {
System.err.println("[ERR] Cryptographer could not generate a SecretKey due to an invalid Key Specification.");
ex.printStackTrace();
return null;
}
}
Само шифрование происходит в функции шифрования:
public byte[] encrypt(byte[] message) {
try {
this._cipher.init(Cipher.ENCRYPT_MODE, this._key, this._paramSpec);
} catch (InvalidKeyException ex) {
System.err.println("[ERR] Cryptographer could not encrypt a message because the provided key is invalid.");
ex.printStackTrace();
return new byte[0];
} catch (InvalidAlgorithmParameterException ex) {
System.err.println("[ERR] Cryptographer could not encrypt a message because the parameters are invalid.");
ex.printStackTrace();
return new byte[0];
}
try {
return this._cipher.doFinal(message);
} catch (IllegalBlockSizeException ex) {
System.err.println("[ERR] Cryptographer could not encrypt a message due to an illegal block size.");
ex.printStackTrace();
return new byte[0];
} catch (BadPaddingException ex) {
System.err.println("[ERR] Cryptographer could not encrypt a message due to bad padding.");
ex.printStackTrace();
return new byte[0];
}
}
И это расшифровывается с помощью функции расшифровки:
public byte[] decrypt(byte[] message) {
try {
this._cipher.init(Cipher.DECRYPT_MODE, this._key, this._paramSpec);
} catch (InvalidKeyException ex) {
System.err.println("[ERR] Cryptographer could not decrypt a message because the provided key is invalid.");
return new byte[0];
} catch (InvalidAlgorithmParameterException ex) {
System.err.println("[ERR] Cryptographer could not decrypt a message because the parameters are invalid.");
}
try {
return this._cipher.doFinal(message);
} catch (IllegalBlockSizeException ex) {
System.err.println("[ERR] Cryptographer could not decrypt a message due to an illegal block size.");
return new byte[0];
} catch (BadPaddingException ex) {
System.err.println("[ERR] Cryptographer could not decrypt a message due to bad padding.");
return new byte[0];
}
}
Кажется, что шифрование работает нормально, но когда я пытаюсь расшифровать сериализованный объект на принимающей стороне, генерируется исключение InvalidKeyException. Сравнение ключей, независимо генерируемых на контроллере и агенте, показывает, что, хотя они получены из одного и того же пароля, они не генерируют идентичные ключи.
Теперь я новичок в шифровании на Java, так что вполне возможно, что я здесь что-то не так делаю. Кажется, в этом есть какой-то случайный элемент, который я пропускаю. Цель состоит в том, чтобы каждая сторона соединения генерировала идентичный ключ из идентичных паролей. Так что я делаю что-то, что явно не так? Если вам нужно увидеть больше кода, дайте мне знать. Я буду рад опубликовать это.