I have a Blackberry app (j2me) the encrypt data and sends it to a server, to a php page, and back again. For the app I use lcrypto-j2me-147 (Bouncy Castle) and mcrypt for the php part. The problem is that they are encrypting the same text and producing different results. Thus the two can't send encrypted data to one another.
My test system: PHP code:
<?php
function printStringToHex($text)
{
$size = strlen($text);
for($i = 0; $i < $size; $i++)
{
echo dechex(ord($text[$i])) . " ";
}
}
function encrypt($key, $input)
{
echo "<PRE>*** Encrypt *** </PRE>";
echo "<PRE>Raw input: " . $input . "</PRE>";
$size = mcrypt_get_block_size('twofish', 'ecb');
echo "<PRE>Block: " . $size . "</PRE>";
$input = pkcs5_pad($input, $size);
echo "<PRE>PKCS#5 padding: ";
echo printStringToHex($input);
echo "</PRE>";
$td = mcrypt_module_open('twofish', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
echo "<PRE>Raw output: " . $data . "</PRE>";
echo "<PRE>Hex output: ";
echo printStringToHex($data);
echo "</PRE>";
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = base64_encode($data);
echo "<PRE>B64 output: " . $data . "</PRE>";
echo "<PRE>B64 output len: ";
echo strlen($data) . "</PRE>";
return $data;
}
function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
$enc = encrypt("The key string", "The plain text string");
The out put is:
Encrypt:
Raw input: The plain text string
Block: 16
PKCS#5 padding: 54 68 65 20 70 6c 61 69 6e 20 74 65 78 74 20 73 74 72 69 6e 67 b b b b b b b b b b b
Raw output: Þˆ2L4ýé6öò8?‰ÛŒÇY˜W‘Š…HEÅ8=a[
Hex output: de 88 32 4c 34 8 fd e9 36 f6 f2 38 3f 89 db 8c c7 59 98 57 91 8a 85 48 45 16 2 c5 38 3d 61 5b
B64 output: 3ogyTDQI/ek29vI4P4nbjMdZmFeRioVIRRYCxTg9YVs=
B64 output len: 44
For the Java part I used an example:
public static byte[] encryptDecrypt(byte[] inputBytes, String keyString, boolean encrypt)
{
try
{
if(encrypt) System.out.println("*** Encrypting *** "); else System.out.println("*** Decrypting *** ");
System.out.println("Key: " + keyString);
System.out.println("Input bytes (String): " + new String(inputBytes));
System.out.print("\nInput bytes (byte[]): ");
printOutBytes(inputBytes);
byte[] keyBytes = keyString.getBytes();
KeyParameter key = new KeyParameter(keyBytes);
TwofishEngine twofish = new TwofishEngine();
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(twofish);
cipher.init(encrypt, key);
byte[] cipherBytes = new byte[cipher.getOutputSize(inputBytes.length)];
int cipherLength = cipher.processBytes(inputBytes, 0, inputBytes.length, cipherBytes, 0);
cipher.doFinal(cipherBytes, cipherLength);
System.out.println("Cipher bytes (String): " + new String(cipherBytes));
System.out.print("\nCipher bytes (byte[]): ");
printOutBytes(cipherBytes);
return cipherBytes;
}
catch(InvalidCipherTextException e)
{
System.err.println(e.getMessage());
}
return null;
}
The out put is:
Encrypting
Key: The key string
Input bytes (String): The plain text string
Input bytes (byte[]): 54 68 65 20 70 6c 61 69 6e 20 74 65 78 74 20 73 74 72 69 6e 67
Cipher bytes (String): ²Rð?=
r¾=??ùUí?9?rtæ?0ÊÃ(½~Å3
Cipher bytes (byte[]): b2 52 f0 87 81 3d 14 a 72 be 3d 85 80 f9 55 ed 9a 39 82 72 74 e6 91 30 ca c3 1 28 bd 7e c5 33
B64 of encText: slLwh4E9FApyvj2FgPlV7Zo5gnJ05pEwysMBKL1+xTM=
B64 len: 44
Any ideas? I suspect it is the Initialization Vector not used by Java?
Many thanx, Andre
I ended up creating a Servlet using the same encryption lib as suggested by Telmo Pimentel Mota