i'm trying to fix a critical bug emerged during a penetration test on our application.
Environment: an old Gupta/SQL Windows desktop application that need the support from a java webapp (hosted on IBM WebSphere) to operate on db/communicate on CICS; during the penetration test we were able to act a Man in The Middle and sniff/send command to the java webapp, getting full access to the db.
As a fix i've thought about implementing Mutual authentication between client and server; unlucky we cannot use TLS / 2-way-ssl since Gupta doesn't support it. (as the Gupta developer say, i'm the java one). So we're trying to implement a simpler MA, adding an encrypted password on every transaction between client and server (made "random" encrypting a static text + timestamp), to be decrypted and verified on every exchange.
Here the problem: on our actual test the two application encrypt the same string in different outputs
This is my aes256 encrypter, with password generated from a String + fixed salt
private static final String SECRET_KEY = "PasswordTest123";
private static final String SALT = "sssshhh!";
public static void main(String[] args) {
TestTest asd = new TestTest();
System.out.println(asd.encrypt("TestStringTestString10:45:12"));
}
public static String encrypt(String strToEncrypt) {
try {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
// we're on java 7 and "PBKDF2WithHmacSHA256" seems not available, got exception
// SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALT.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
byte[] message = cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8));
String s = new String(message);
System.out.println(s);
String encoded = DatatypeConverter.printBase64Binary(message);
return encoded;
} catch (Exception e) {
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
Output:
R_.m]wcý7uÒ¨Im„çYSç.?®ôZ†»Y
Ul8uf21dd2P9Azd10qgOSW2E51lT5y4/rvQIWoa7WRY=
Here the Gupta/SQL Windows app encrypt, with the same password/parameters:
lDEd+PLT5wmPTyZhqvGMgbKc9djCrJLjsZeGlYnjO8A=
Notes: on the desktop app we're using the CryptEncrypt class to perform encryption, but seems to not be a Salt from password option.
i'm no AES256 expert, which is the parameter that is giving us a different result? the salt? the iv? also i'd appreciate some links to doc, everything i found are "commercial" articles about AES, i need something to understand salt-iv
Thanks a lot!
EDIT: If we use a different Salt/IV on both sides, we will be able to encrypt/decrypt the string?