Home » Php » encryption – Unexpected result decrypting using PHP AES CCM mode

encryption – Unexpected result decrypting using PHP AES CCM mode

Posted by: admin July 12, 2020 Leave a comment

Questions:

I am attempting to reproduce an encryption operation using AES-256-CCM that is currently performed in Java with the Bouncy Castle provider. When attempting the same operation in PHP using openssl I cannot find a set of parameters that produces the same output.

As the AEAD modes were recently added to PHP (7.1), documentation on how this works is scarce.

A minimum example of the “working” encryption in Java looks like:

    public static void main(String args[]) {
    try {
        java.security.Security.addProvider(new BouncyCastleProvider());
        byte[] key = Base64.decodeBase64("Z4lAXU62WxDi46zSV67FeLj3hSK/th1Z73VD4/y6Eq4=".getBytes());
        byte[] iv = Base64.decodeBase64("rcFcdcgZ3Q/A+uHW".getBytes());

        SecretKey aesKey = new SecretKeySpec(key, 0, key.length, "AES");
        Cipher aesCipher = Cipher.getInstance("AES/CCM/NoPadding", "BC");
        aesCipher.init(1, aesKey, new IvParameterSpec(iv));

        byte[] encrypted = aesCipher.doFinal("test".getBytes());
        System.out.println(Hex.encodeHex(encrypted));

        // Output: 411d89ff74205c106d8d85a8
    }
    catch (Throwable e) {
        e.printStackTrace();
    }
}

As I am trying to re-produce this using different two different libraries and languages I have set the key and iv to known values.

When trying to re-produce this using PHP and openssl I am trying with the following code

$key = base64_decode("Z4lAXU62WxDi46zSV67FeLj3hSK/th1Z73VD4/y6Eq4=");
$iv = base64_decode('rcFcdcgZ3Q/A+uHW');
$data = 'test';
$tag = null;

$encrypted = openssl_encrypt($data,'aes-256-ccm', $key,OPENSSL_RAW_DATA, $iv, $tag,"",8);
echo(bin2hex($encrypted . $tag));
// d1a7403799b8c37240f36edb

Clearly the results do not match. In search of an answer as to what is incorrect I created the same operation using SJCL in javascript. The example for that is:

var data = "test";
var key = sjcl.codec.base64.toBits("Z4lAXU62WxDi46zSV67FeLj3hSK/th1Z73VD4/y6Eq4=");
var iv = sjcl.codec.base64.toBits("rcFcdcgZ3Q/A+uHW");
var  p = { 
        adata: "",
        iter: 0,
        mode: "ccm",
        ts: 64,
        ks: 256,
        iv: iv,
        salt: ""
        };
var encrypted = sjcl.encrypt(key, data, p, {}); 
console.log(encrypted);
// Output: {"iv":"rcFcdcgZ3Q/A+uHW","v":1,"iter":0,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"","ct":"QR2J/3QgXBBtjYWo"}

// QR2J/3QgXBBtjYWo === 411d89ff74205c106d8d85a8

The Bouncy Castle and SJCL libraries produce the same output but I can’t tell what is different.

I have tried pre-processing the key with PBKDF2 as suggested in Encrypt in Javascript with SJCL and decrypt in PHP with no success. I have tried SHA256’ing the key with no success.

Why is the output in php/openssl different than Bouncy Castle and SJCL?

How to&Answers: