views:

91

answers:

4

Hi,

I have to pass some strings from a java servlet to a php script. What options are there for encrypting the strings? I'd need a method that is implemented for both java and php (like..a caesar cipher...). Is there any standard encryption method I should be able to get a library for both java and php?

I want to encrypt the strings on the java side, pass to the php script, then let the php script decrypt them.

I can't use https due to the limitations of the provider I'm using.

Thanks

A: 

Jasypt (http://www.jasypt.org/) will use any algorithm you want. Should be able to implement any of the common algos in a few minutes.

bwawok
A: 

Look at the mcrypt extension for PHP. One of those almost certainly exists in Java.

Kalium
A: 

Most of the standard encryption algorithms are available in both PHP and Java.

Have a look at:

As you can see, both of them support DES, TripleDES, RC2 at the least.

casablanca
+6  A: 

Hopefully this can get you started. Error handling is missing and the secret key is hard coded. Both of those would need to be addressed for production quality code. From the Java side you can use the Java Cryptography Architecture (JCA):

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.mail.internet.MimeUtility;

public final void testTesting() throws Exception {
    final String plainText = "plain text";
    final String result = encrypt(plainText);
    System.out.println(result);
}

public String encrypt(final String plainText) throws Exception {
    final byte[] data = plainText.getBytes("UTF-8");
    final byte[] encoded = encrypt(data);
    final String result = new String(encoded).replaceAll("[\r\n]", "");
    return result;
}

public byte[] encrypt(final byte[] data) throws Exception {
    // this is just an example key, real code should use a properly generated shared secret
    final byte[] secret = new byte[] {42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42};
    final SecretKeySpec key = new SecretKeySpec(secret, "AES");

    final Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    encryptCipher.init(Cipher.ENCRYPT_MODE, key);
    final byte[] iv = encryptCipher.getIV();
    final byte[] encrypted = encryptCipher.doFinal(data);

    final int outputLength = encrypted.length;
    final int ivLength = iv.length;

    final byte[] results = new byte[outputLength + ivLength];
    System.arraycopy(iv, 0, results, 0, ivLength);
    System.arraycopy(encrypted, 0, results, ivLength, outputLength);

    final ByteArrayOutputStream encoded = new ByteArrayOutputStream();
    final OutputStream encoder = MimeUtility.encode(encoded, "base64");
    encoder.write(results);
    encoder.flush();
    encoder.close();
    return encoded.toByteArray();
}

That code also requires Java Mail for the base 64 encoding. You could use the base 64 encoder of your choice if mail.jar is unavailable.

From the PHP side, you are going to need Mcrypt.

<?php
$key = base64_decode('KioqKioqKioqKioqKioqKg==');
$input = base64_decode($_GET['input']);
$plain_text = substr($input, 16);
$initialization_vector = substr($input, 0, 16);
echo pkcs5_unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $plain_text, MCRYPT_MODE_CBC, $initialization_vector));

function pkcs5_unpad($text) {
    $pad = ord($text{strlen($text)-1});
    if ($pad > strlen($text)) {
        return false;
    }
    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
        return false;
    }
    return substr($text, 0, -1 * $pad);
}
?>

The function pkcs5_unpad was copied from here since it seems that PHP Mcrypt doesn't include support for PKCS5 padding. The Java code prefixes the data with the initialization vector used to encrypt it. Subsequently the PHP code splits it into two, the initialization vector and the encrypted data.

This code uses 128 bit AES (Rijndael) in CBC mode which should be secure enough for most uses. In addition to the simple encryption, I recommend using an HMAC as described here to ensure the data isn't tampered with. To perform the HMAC in Java, use the Mac class. For PHP, see Mhash.

laz
Wow yeah this is exactly what I need. I'll give it a try, thanks for setting all this up, will report back.