У меня есть файл, зашифрованный в AES 128 CBC (с openssl в cpp). Шифрование выполнено с неверным размером iv (8 вместо 16). Это факт, это неправильно, и я ничего не могу с этим поделать. Файл, который я получаю, выглядит следующим образом:
[8 бит IV] [Зашифрованные данные]
Мне нужно прочитать этот файл с помощью Java (android), но я не могу получить правильный результат.
Вот то, что я использую для расшифровки файла:
public String decrypt(byte[] key, byte[] datasencrypted) {
// Split IV and actual Datas into 2 differents buffers
int dataSize = datasencrypted.length - 8; // 8 = wrong iv size
byte[] encrypted = new byte[dataSize];
byte[] ivBuff = new byte[8];
System.arraycopy(datasencrypted,0,ivBuff,0,8);
System.arraycopy(datasencrypted,8,encrypted,0,dataSize);
try {
IvParameterSpec iv = new IvParameterSpec(ivBuff);
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(encrypted);
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
Очевидно, этот код генерирует исключение InvalidAlgorithmParameterException: ожидаемая длина IV - 16. Если я изменю размер буфера iv на 16, не болееисключение, но конечный результат - просто бред.
Кроме того, ключ определен как unsigned char [] в CPP, поэтому, чтобы преобразовать его в byte [] в Java, я просто приведу значения следующим образом:
mKey = new byte[]{(byte)0x8c,(byte)0x96,0x5f,.....}};
- Можно ли расшифровать этот файл в java (он работает на стороне cpp)?
- Как узнать, какой тип заполнения использовать?
- приведение значения ключа может быть проблемой?
--- РЕДАКТИРОВАТЬ --- Как предлагается здесь, это код CPP, который может расшифровать файл:. AES_KEYLEN = 128.
AES_ROUND = 5.
size_t Helper::DecryptAES(unsigned char* encMsg, size_t encMsgLen, unsigned char** decMsg)
{
size_t decLen = 0;
size_t blockLen = 0;
*decMsg = (unsigned char*)malloc(encMsgLen);
if (*decMsg == nullptr) return 0;
if (!EVP_DecryptUpdate(mAESDecryptCtx, (unsigned char*)*decMsg, (int*)&blockLen, encMsg, (int)encMsgLen)) {
return 0;
}
decLen += blockLen;
if (!EVP_DecryptFinal_ex(mAESDecryptCtx, (unsigned char*)*decMsg + decLen, (int*)&blockLen)) {
return 0;
}
decLen += blockLen;
return decLen;
}
bool Helper::InitAES(unsigned char* key, unsigned char* salt)
{
mAESEncryptCtx = static_cast<EVP_CIPHER_CTX*>(malloc(sizeof(EVP_CIPHER_CTX)));
mAESDecryptCtx = static_cast<EVP_CIPHER_CTX*>(malloc(sizeof(EVP_CIPHER_CTX)));
mAESKey = static_cast<unsigned char*>(malloc(AES_KEYLEN / 8));
mAESIv = static_cast<unsigned char*>(malloc(AES_KEYLEN / 8));
int size = EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha256(), salt, key, AES_KEYLEN / 8, AES_ROUNDS, mAESKey, mAESIv);
if (size != AES_KEYLEN / 8)
{
return false;
}
EVP_CIPHER_CTX_init(mAESEncryptCtx);
if (!EVP_EncryptInit_ex(mAESEncryptCtx, EVP_aes_128_cbc(), nullptr, mAESKey, mAESIv))
return false;
EVP_CIPHER_CTX_init(mAESDecryptCtx);
if (!EVP_DecryptInit_ex(mAESDecryptCtx, EVP_aes_128_cbc(), nullptr, mAESKey, mAESIv))
return false;
return true;
}
Здесь IvSIze в порядке, но когда iv добавляется в файл, читается только 8 бит вместо 16.