当前位置: 首页 > 知识库问答 >
问题:

AndroidNDK中的C/C加密(Rijndael密码)

梁鸿风
2023-03-14

我想把我的C#(托管)解密方法转换成Android NDK, C/C(NO JAVA)

我看到有加密。在JAVA方面,但我想远离任何JNI,我还看到有mcrypt和crypt,但找不到适用于android的编译库。

这里有一个C#的例子,我想把它翻译成C/C

    public byte[] DecryptBytes(byte[] encryptedBytes)           
    {
    RijndaelManaged RijndaelCipher = new RijndaelManaged();


            RijndaelCipher.Mode = CipherMode.CBC;

            ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(Bytes32_KEY, Bytes16_IV);

            MemoryStream memoryStream = new MemoryStream(encryptedBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
            byte[] plainBytes = new byte[encryptedBytes.Length];

            int DecryptedCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length);

            memoryStream.Close();
            cryptoStream.Close();

            return plainBytes;

    };

更新到目前为止,我发现最好的方法是使用openSSL AES,我已经下载了一个预编译的Android库,我只是在努力让它与一些已经发布的示例一起工作,比如c代码示例

void test_enc(){

    int keylength = 256;

    //  // 256bit KEY
        uint8_t key[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};

        //128bit IV
        uint8_t iv[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};


        //input data
        uint8_t input[64] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

    size_t inputslength = 10;
    int x;

    uint8_t *aes_key = key;

    uint8_t *aes_input = input;

    uint8_t *iv_enc = iv;
    uint8_t *iv_dec = iv;

    // buffers for encryption and decryption
    const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
    uint8_t *enc_out = (uint8_t*)malloc(sizeof(uint8_t) *encslength);
    uint8_t *dec_out = (uint8_t*)malloc(sizeof(uint8_t) *inputslength);
    memset(enc_out, 0, encslength);
    memset(dec_out, 0, inputslength);

    // so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256
    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(aes_key, keylength, &enc_key);
    AES_cbc_encrypt(input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT);

    AES_set_decrypt_key(aes_key, keylength, &dec_key);  
    AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);

    LOGI("Before:");
    for(x=0;x<inputslength;x++)
        LOGI("%02x, ", input[x]);

    LOGI("Encrypted:");
    for(x=0;x<encslength;x++)
        LOGI("%02x, ", enc_out[x]);

    LOGI("Decrypted:");
    for(x=0;x<encslength;x++)
        LOGI("%02x, ", dec_out[x]);
};

加密的字节和c#不一样,然后解密没有返回到输入,我哪里出错了?

共有2个答案

周麒
2023-03-14

开放SSL是一个相当大的库(如果你关心APK大小)

可以在C中使用微小的AES(可以和C一起使用)

我已将其添加到Android项目(CMake)

https://github.com/anonym24/Android-Tiny-AES-NDK

牧飞鹏
2023-03-14

解决了的:

问题是,在加密后,持有IV的数组似乎被更改,因此您需要在解密结果之前重置回去

使用预构建的OpenSSL for Android,您可以在这里找到OpenSSL-for-Android-pre build

上面的代码只记得在每次调用之前设置IV来AES_cbc_encrypt。

 类似资料:
  • 问题内容: 我正在用Java实现与第三方应用程序的通信。作为登录过程的一部分,第三方应用程序正在发送一个加密的字符串,我必须对其进行解码并发回。我已经花了将近2天的时间进行糊涂和阅读文章,但是我找不到实现此目的的正确方法。 我有一个测试用例,其中加密的字符串为“ c1W2YO1vYQzu6czteEidrG0U4g5gT4h57vAlP7tdjcY =“,使用密码“ GAT”解密的字符串必须返回“

  • 问题内容: 更新 我已经对C#代码进行了更改,因此它使用的块大小为256。但是现在,您好世界看起来像这样http://pastebin.com/5sXhMV11,我无法弄清楚应该使用rtrim()获得什么一团糟的最后。 另外,当您说IV应该是随机的时,您的意思是不要再使用一次相同的IV,否则我编码的方式错误吗? 再次感谢! 你好 我正在尝试使用在C#中加密的PHP解密字符串。我似乎无法让PHP使用

  • 我曾在互联网上寻找解决问题的有效方法,但我尝试的一切都不奏效。我在两种语言之间得到了不同的结果。 在PHP中,我有以下代码: 和C#中的以下代码: 我有另一个CalcMd5函数,它接受一个byte[](与上面的函数类似,但没有GetBytes部分)。 需要加密的密钥和字符串在PHP和C#中都是相同的: 键:“24ACD2FCC7B20B8BD33FF45176F03061A09B729487E10

  • 我试图解密C#加密数据在Java没有成功。我用的是128位密钥 这是java代码: 你知道会出什么问题吗? 谢谢 使现代化 对不起,我太笨了,我忘了写实际的错误消息。这是: 线程“main”javax中出现异常。加密。BadPaddingException:组织中的填充块已损坏。弹跳船舱。jcajce。供应商。对称的。util。基本分组密码。javax上的engineDoFinal(未知源代码)。

  • 我试图用C#加密一些(cookie)数据,然后用PHP解密。我选择使用Rijndael加密。我几乎让它工作,除了只有一部分的文本被解密!我从这个例子开始工作:用C#解密PHP加密的字符串 这是我正在加密的文本(JSON)(删除敏感信息): 所以我登录到 C# 应用程序,该应用程序从存储的密钥和 IV 创建/编码 cookie,然后重定向到应该解密/读取 cookie 的 PHP 应用程序。当我解密

  • 我正在创建一个应用程序,我保存了一些隐私文档。我想把那些文件保存为加密格式。 我在谷歌搜索C语言的AES加密/解密alto。我找不到实现AES的标准算法。