AES256 password exchange for Mutual authentication - different encrypt result between client - server

139 views Asked by At

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?

0

There are 0 answers