У меня есть файл, зашифрованный с использованием следующего кода в c:
unsigned char ckey[] = "0123456789ABCDEF";
unsigned char iv[8] = {0};
AES_set_encrypt_key(ckey, 128, &key);
AES_ctr128_encrypt(indata, outdata, 16, &key, aesstate.ivec, aesstate.ecount, &aesstate.num);
Я должен расшифровать этот файл, используя Java, поэтому я использовал код ниже, чтобы сделать это:
private static final byte[] encryptionKey = new byte[]{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
byte[] iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
IvParameterSpec ips = new IvParameterSpec(iv);
Cipher aesCipher = Cipher.getInstance("AES/CTR/NoPadding");
SecretKeySpec aeskeySpec = new SecretKeySpec(encryptionKey, "AES");
aesCipher.init(Cipher.DECRYPT_MODE, aeskeySpec, ips);
FileInputStream is = new FileInputStream(in);
CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), aesCipher);
copy(is, os);
os.close();
Код JAVA не дает мне никакой ошибки, но вывод неправильный.
Что я делаю не так?
Мои главные сомнения в том, правильно ли я использую заполнение (также безуспешно пробовал PKCS5Padding) и правильны ли ключ и iv (не знаючто действительно делает функция AES_set_encrypt_key ...).
** РЕДАКТИРОВАТЬ **
Я думаю, что у меня есть ответ на мой собственный вопрос, но у меня все еще есть некоторые сомнения.
CTR означает режим счетчика.Функция AES_ctr128_encrypt получает в качестве параметров фактический счетчик (ecount) и количество используемых блоков (num).
Файл шифруется блоками по 16 байт, например:
for(int i = 0; i < length; i+=16)
{
// .. buffer processing here
init_ctr(&aesstate, iv); //Counter call
AES_ctr128_encrypt(indata, outdata, 16, &key, aesstate.ivec, aesstate.ecount, &aesstate.num);
}
функция init_ctr делает это:
int init_ctr(struct ctr_state *state, const unsigned char iv[8])
{
state->num = 0;
memset(state->ecount, 0, 16);
memset(state->ivec + 8, 0, 8);
memcpy(state->ivec, iv, 8);
return 0;
}
Это означает, что перед каждым шифрованием / дешифрованием код С сбрасывает счетчик и ivec.
Я пытаюсь расшифровать файл какцелое в яве.Это, вероятно, означает, что Java использует счетчик правильно, но код C не так, как он сбрасывает счетчик в каждом блоке.
Правильно ли мое расследование?
У меня нет абсолютно никакого контроля над Cкод, который вызывает openssl.Есть ли способ сделать то же самое в JAVA, то есть сброс счетчика в каждом блоке из 16?(API запрашивает только ключ, алгоритм, режим и IV)
Мой единственный другой вариант - использовать openssl через JNI, но я пытался этого избежать ...
Спасибо!