I have my AES 256 encryption method implemented and working fine in Java as follows!
private static final byte[] IV = {
0, 2, 4, 8, 16, 32, 64, 127,
127, 64, 32, 16, 8, 4, 2, 0
};
//actual encryption over here
private static byte[] encrypt(byte[] raw, byte[] clear) throws
Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = null;
if(isIVUsedForCrypto) {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(IV));
}
else
{
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
}
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
The byte array that is returned from the above method is finally converted to a HEX string using the following toHex
method.
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
So the end result using Java AES 256 encryption code is a HEX String.
Now for the Qt part,
QByteArray IV("0, 2, 4, 8, 16, 32, 64, 127,127, 64, 32, 16, 8, 4, 2, 0");
QString encrypt(QByteArray r, const QString &password)
{
const char *sample = r.data();
string plain = password.toStdString();
string ciphertext;
// Generate Cipher, Key, and CBC
byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ];
StringSource( reinterpret_cast<const char *>(sample), true,
new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)) );
memset( iv, 0x00, AES::BLOCKSIZE );
CBC_Mode<AES>::Encryption Encryptor( key, sizeof(key), iv );
StringSource( plain, true, new StreamTransformationFilter( Encryptor,
new HexEncoder(new StringSink( ciphertext ) ) ) );
return QString::fromStdString(ciphertext);
}
And from the main method i call the above function
QString encrypted = encrypt(result, "test");
where "result" is a QByteArray
that I pass to encrypt as done similarly in java.
The byte arrays in both cases Java and Qt are obtained the same. I have verified that.
My problem
The encryption logic for Qt especially is failing somewhere due to which the HEX
result obtained via Java and Qt don't match.
Can anyone tell me what I am doing wrong in the Qt part. Am I not using the IV
or the QByteArray
result
correctly?
I guess your Java implementation misses a hash step on the key. I'm using a SHA256 hash of the key. To test c++ implementation, change code to this:
Initialization vector is different in your Java code and Qt:
And in C++:
So you need to use same IV for both schemes.
Update:
In order to provide an IV for CBC mode of AES, you need to specify IV as you do in Java:
Note that AES::BLOCKSIZE is defined in library headers and it is
16
.