安卓中C语言的AES加密

5
我想在我的Windows 7(64位)电脑上加密文件,然后在Android设备上解密。我使用以下算法来加密文件:http://gladman.plushost.co.uk/oldsite/AES/aes-byte-29-08-08.zip。我将文件加密后传输到SD卡。但是,当我尝试在Android设备上解密它们时,结果不同,文件变得完全无法读取。请问这是什么问题?
jbyteArray Java_com_example_hellojni_HelloJni_decrypt(JNIEnv* env, jobject thiz, jstring fileName) {
    ......

    /* read the file into the buffer */
    size_t result = fread (buffer_in, 1, file_size, fin);
    if (result!=file_size) { fputs("Reading error", stderr); exit(3); } /* end if */
    fclose(fin);

    /* decrypt file */
    aes_context ctx[1];
    aes_set_key(key, 16, ctx);
    long i;
    for (i=0; i<num_block; i++) {
        long begin = i*16;
        char *block = copyBlock(buffer_in, file_size, begin, 16), /* copy buffer_in[begin] ~ buffer_in[begin+16-1] to block[] */
             *tmp = (char*)malloc(sizeof(char)*16);
        aes_decrypt(block, tmp, ctx);
        fillBuffer(buffer_out, out_size, tmp, begin, 16); /* copy tmp[] to buffer_out[begin] ~ buffer_out[begin+16-1] */
        free(tmp);
        free(block);
    } /* end for */
    ......
} /* end Java_com_example_hellojni_HelloJni_decrypt() */

我知道差异发生在aes.c文件中:

return_type aes_set_key( const unsigned char key[], length_type keylen, aes_context ctx[1] ) {
    ......
    for( cc = keylen, rc = 1; cc < hi; cc += 4 ) {
        uint_8t tt, t0, t1, t2, t3;

        /* difference begins here */
        t0 = ctx->ksch[cc - 4];
        t1 = ctx->ksch[cc - 3];
        t2 = ctx->ksch[cc - 2];
        t3 = ctx->ksch[cc - 1];         
        .......
    } /* end for */
    return 0;
} /* end aes_set_key() */

但为什么?!

急需帮助!

我也将buffer_in和buffer_out更改为“unsigned char *”,但仍然无法工作... - user538565
字符串是相同的;文件不可读... 我猜 Android 和 PC 的 uint_8t 之间存在差异。 - user538565
你能否在Pastebin上上传一些示例? - Mascarpone
提示:Bouncy Castle提供了纯Java密码实现,可用于比较本地解密代码的结果与成熟加密引擎的结果。 - JimmyB
我在电脑上加密和解密文件都能正常工作。但是如果我在电脑上加密,然后在安卓设备上解密,就无法正常工作了... - user538565
显示剩余3条评论
1个回答

2
一般来说,你不应该自己实现AES(或任何其他加密算法)(除非为了学习它的工作原理)-在生产中使用已知的库。
对于Java(你在这里使用JNI,是吧?),请使用JRE附带的加密API(javax.crypto)。同样的API也适用于Android(可以使用引擎附带的API或BouncyCastle变体)。
然后,请确保你正在使用:
- 相同的操作模式(例如ECB(不推荐),CBC,CTR,CFB,OFB)用于块密码。我不知道你的C实现使用哪种模式,也许是ECB。我想默认情况下Android使用的是CBC。 - 相同的密钥进行加密和解密。

Java的AES太慢了,这就是为什么我使用了上面提到的算法。但是,如果我在PC上加密文件,然后在Android上解密它们,或者反过来,解密后的文件是无法读取的... - user538565
你的C语言实现更快吗?我真的很怀疑。无论如何,如果你必须这样做,请使用像OpenSSL这样的库。(而且真的,请查看操作模式。) - Paŭlo Ebermann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接