-1

Encrypt with JAVA (jasypt) and Decrypt with PHP - Whats the less vulnerable Algorithm?


Im working on a legacy system that has the following tasks:

1) The Java Application saves some encrypted data on a mysql database. This happens very rarely. The data is saved once and rarely updated.

2) A PHP page loads that encrypted data from the mysql database and uses it for internal logic. This php page must be able to decrypt it internally, but not to encrypt it.

3) The java Application also loads the encrypted data from the mysql database and decrypts it for internal purposes.

In another words, I have a Java application that encrypts and decrypts data. And I have a php single page that must be able to decrypt the data.


Currently, I must re-do this with new crypto algorithms. I researched at stackoverflow and many are saying to stay away from MD5 and DES. As far as I understood, I must go with AES, So Ive came up with the following java CODE below. However:

a) Im unsure how to decrypt with php, I normally use openSSL but I dont know the equivalent algo name in php.

<?php

ini_set('display_errors', 1);

$salt = 'nXdHqFg74g22g4Vq';
$key = $salt; // ? not sure

$data = 'uVJ+m3FGkzFTCQXpZJysmo53rWh5+5L9dWzyyD8xues=';
$method = "AES-256-CFB"; //not sure which

//openssl_decrypt ( string $data , string $method , string $key [, int $options = 0 [, string $iv = "" [, string $tag = "" [, string $aad = "" ]]]] ) : string
echo openssl_decrypt($data, "AES-256-CFB", $key);


?>

b) Is this safe enough for general purposes? I dont need anything awesomely secure just enough since this data mostly travel through https.

import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.iv.IvGenerator;
import org.jasypt.iv.StringFixedIvGenerator;

public class MyCryptoTest {

    //private static final byte[] key = "nXdHqFg74g22g4Vq".getBytes();
    private static final byte[] key = {110, 88, 100, 72, 113, 70, 103, 55, 52, 103, 50, 50, 103, 52, 86, 113};

    private static PooledPBEStringEncryptor textCryptor = new PooledPBEStringEncryptor();

    public static void main(String args[]) throws Exception {

        //System.out.println(Arrays.toString(key));
        //System.out.println(Arrays.toString("nXdHqFg74g22g4Vq".getBytes(Charset.forName("UTF-8"))));
        String input = "stackoverflow";
        String x = encrypt(input);
        String y = decrypt(x);

        System.out.println(x);
        System.out.println(y);

        System.out.println("Test Result: " + input.equals(y));

    }

    static {
        IvGenerator ivGenerator = new StringFixedIvGenerator("some_random_word?");
        textCryptor.setPoolSize(2);
        textCryptor.setPassword(new String(key));
        textCryptor.setAlgorithm("PBEWithHMACSHA512AndAES_256");
        textCryptor.setIvGenerator(ivGenerator);
    }

    public static String encrypt(String strClearText) throws Exception {
        String strData = "";

        try {
            strData = textCryptor.encrypt(strClearText);

        } catch (Exception ex) {
            ex.printStackTrace();
            throw new Exception(ex);
        }
        return strData;
    }

    public static String decrypt(String strEncrypted) throws Exception {
        String strData = "";

        try {
            //System.out.println(strEncrypted);
            strData = textCryptor.decrypt(strEncrypted);

        } catch (Exception ex) {
            throw new Exception(ex);
        }
        return strData;
    }

}

Important Quotes from the references:

Ideally you should move away from DES and since this padding is going to be a problem in PHP, why not see if you can change the encryption algorithm to something less troublesome and more secure?

To help you can show this page: http://www.ietf.org/rfc/rfc4772.txt, where it is succinctly expressed that DES is susceptible to brute force attacks, so has been deprecated and replaced with AES.

Community♦ 111 silver badge answered Dec 17 '13 at 17:15

James Black

Both MD5 and DES have known vulnerabilities and should not be used. – SLaks Apr 24 '12 at 14:45

MD5 is actually fine for key derivation, single DES is only fine for real time, short lived encryption purposes (which is basically never). Both should be avoided of course, especially if you don't know what you are doing. – Maarten Bodewes Apr 25 '12 at 20:06

References:

Decrypt ( with PHP ) a Java encryption ( PBEWithMD5AndDES )

Replacing JAVA with PHP for PKCS5 encryption

How can I list the available Cipher algorithms?

KenobiBastila
  • 539
  • 4
  • 16
  • 52
  • 1
    The algorithm used as a IV so you will need to provide that for us – John Conde May 30 '20 at 17:40
  • Ive added one. Does that do the trick? – KenobiBastila May 30 '20 at 17:54
  • 1
    When I run this encrypted test through 127 ciphers using the information provided I do not get positive results. I used `some_random_word` and `some_random_word?` as IVs and they failed. Are you sure that is the correct value? – John Conde May 30 '20 at 18:05
  • Yes, the java class runs smoothly: – KenobiBastila May 30 '20 at 18:07
  • > Task :runSingle uVJ+m3FGkzFTCQXpZJysmo53rWh5+5L9dWzyyD8xues= stackoverflow Test Result: true – KenobiBastila May 30 '20 at 18:07
  • Ive updated the php data. Its good now. – KenobiBastila May 30 '20 at 18:08
  • Same results. My gut tells me we don't have the correct IV to use to decrypt with. – John Conde May 30 '20 at 18:17
  • I dont understand. I just ran that on java and it worked fine. – KenobiBastila May 30 '20 at 18:20
  • Is there any other algorithm I could use instead? – KenobiBastila May 30 '20 at 18:21
  • It's not that it doesn't work in Java, but the IV is a value used to generate the encrypted value. Without knowing it, you cannot decrypt it. I do not know enough Java to know how to get the IV used in your code. Your next step is to figure out how to get that IV value. Once you have that I can test against all of those ciphers again. – John Conde May 30 '20 at 18:22
  • `byte[] key = "nXdHqFg74g22g4Vq".getBytes();` looks suspicious: are you sure the literal is in byte per character? Assign the variable without using strings and try again. – AmigoJack May 30 '20 at 20:28
  • Done. I converted and used the byte instead of the string. its the same key. But I just did the conversion manually – KenobiBastila May 30 '20 at 23:19
  • If your code contains a method named `StringFixedIvGenerator` then you don't understand encryption enough to continue. Learn crypto before proceding. Edit: oh, it is JASYPT. Well that goes to show I guess, those nutters definitely don't get encryption / decryption. – Maarten Bodewes May 31 '20 at 21:37

1 Answers1

2

Concerning the Jasypt code the following has to be considered:

  • PBEWithHMACSHA512AndAES_256 uses PBKDF2, i.e. by means of digest, password, salt and iteration count the encryption / decryption key is derived, i.e. these parameters are also needed for decryption. Algorithm and digest can be derived directly: AES-256 and SHA-512. As mode of operation CBC is applied.
  • The posted code generates a different ciphertext each time due to a randomly generated salt. A user defined salt can be passed to the PooledPBEStringEncryptor instance textCryptor analogous to the IV with:

    textCryptor.setSaltGenerator(new StringFixedSaltGenerator(<YourSalt>));
    
  • Jasypt uses the blocksize (16 bytes for AES) as salt size. Smaller salts cause an exception, larger salts are simply truncated.

  • The processing of the IV is analogous to the salt: Smaller IVs cause an exception, larger IVs are truncated.
  • If the iteration count isn't set explicitly with PooledPBEStringEncryptor#setKeyObtentionIterations(<iteration count>), 1000 is used by default.
  • Jasypt expects an ASCII-string as password (just for completeness, as this is true for the posted code).

With the Salt A16bytesSalt_012 the Jasypt code provides the following ciphertext: Lg01eeYnujbof0Wy9rs3XQ==. This ciphertext can be decrypted with PHP using hash_pbkdf2 as follows:

<?php
$salt = 'A16bytesSalt_012'; // First 16 bytes of the salt used in Jasypt code
$iv = 'some_random_word';   // First 16 bytes of the IV used in Jasypt code
$iterations = 1000;         // Jasypt default
$password = array(110, 88, 100, 72, 113, 70, 103, 55, 52, 103, 50, 50, 103, 52, 86, 113); // Password used in Jasypt code
$password = implode(array_map("chr", $password));
$key = hash_pbkdf2("sha512", $password, $salt, $iterations, 32, TRUE);

$data = 'Lg01eeYnujbof0Wy9rs3XQ=='; // Ciphertext from Jasypt code 
$method = "aes-256-cbc";            // Algorithm and mode used in Jasypt code
echo openssl_decrypt($data, $method, $key, 0, $iv);
?>
Topaco
  • 40,594
  • 4
  • 35
  • 62