簡體   English   中英

AES / CBC / PKCS5在JAVA和JNI中填充不同結果

[英]AES/CBC/PKCS5Padding different results in JAVA and JNI

我有一個用於加密的Java代碼,如下所示

byte[] encrypt(byte[] clearData) {
   byte[] passwordKey = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,0x0f};
   byte[] rawSecretKey = new byte[]{0x34, (byte) 0xA4, 0x16, 0x09, 0x77, (byte) 0x85, (byte) 0xB4, 0x31,
                                                0x75, 0x12, (byte) 0x92, (byte) 0xDD, (byte) 0xCA, 0x15, (byte) 0xAB, (byte) 0xBA};
   secretKey = new SecretKeySpec(passwordKey, "AES");
   ivParameterSpec = new IvParameterSpec(rawSecretKey);
   Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
   aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);

   byte[] encryptedData;
   encryptedData = aesCipher.doFinal(clearData);

   return encryptedData;
}

我必須將此代碼移植到JNI。 我建立了openssl並制作了JNI包裝函數,如下所示:

JNIEXPORT jbyteArray JNICALL Java_axon_voiceassistant_utils_JNIUtils_getcr(JNIEnv *env, jclass cls, jbyteArray srcData)
    {
        int srcLen=env->GetArrayLength(srcData);
        unsigned char* indata = new unsigned char[srcLen];
        env->GetByteArrayRegion (srcData, 0, srcLen, reinterpret_cast<jbyte*>(indata));

        const unsigned char ukey[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,0x0f};
        unsigned char iv [] = {0x34, 0xA4, 0x16, 0x09, 0x77,0x85, 0xB4, 0x31,
                               0x75, 0x12, 0x92,0xDD, 0xCA, 0x15, 0xAB, 0xBA};

        const size_t encs_length = ((srcLen + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
        unsigned char enc_data[encs_length];
        memset(enc_data, 0, sizeof(enc_data));


        AES_KEY key;
        memset(&key, 0, sizeof(AES_KEY));

        AES_set_encrypt_key(ukey, 128, &key);
        AES_cbc_encrypt(indata, enc_data, srcLen, &key, iv, AES_ENCRYPT);

        jbyteArray bArray = env->NewByteArray(encs_length);
        jboolean isCopy;
        void *enc_copy = env->GetPrimitiveArrayCritical((jarray)bArray, &isCopy);
        memcpy(enc_copy, enc_data, encs_length);

        env->ReleasePrimitiveArrayCritical( bArray, enc_copy, 0);

        return bArray;

    }

但是,使用JNI版本不會獲得與使用Java版本相同的結果。 可能是什么問題呢?

您已在JNI代碼中零填充了純文本:

const size_t encs_length = ((srcLen + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
unsigned char enc_data[encs_length];
memset(enc_data, 0, sizeof(enc_data));

但是您的Java代碼使用的是PKCS#7填充。 其中之一將需要更改。

注意:我認為(基於一些研究)默認情況下, AES_cbc_encrypt執行零填充,因此您自己執行此操作的步驟可能是多余的。

要解決此問題,請在您的JNI代碼中手動實現PKCS#7填充(這實際上非常簡單),或者考慮使用了解如何填充數據的高級EVP函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM