BruceWind / AESJniEncrypt

🛡 Make safest code in Android. (基于libsodium实现chacha20算法,key在native中,防止被二次打包){长期维护,请star,勿fork}
Other
1k stars 164 forks source link

Could you please support AES256/CBC/PKCS7Padding? #33

Open VincentChen1212 opened 5 years ago

VincentChen1212 commented 5 years ago

HI

This is a good Project.

and Is this Project Support AES256/CBC/PKCS7Padding ??? or something can reference ??

Thanks

BruceWind commented 5 years ago

Thanx for your issue. Im going to add some algorithms in few weeks. I have a lot of plan ,but Im too lazy. sorry.

BruceWind commented 5 years ago

Hi ,man: i wasn’t lazy today. i made the repo -> https://github.com/BruceWind/CryptoPPInNDK.

some algoritms will soon.

VincentChen1212 commented 5 years ago

Hi my Hero,

Many Many Many Many Many Thanks, I Very Need AES256/CBC/PKCS7Padding with C, In all the Github, I can't find any repo

Thanks you again

BruceWind commented 5 years ago

you are welcome! Im busy this week, i hava a lot of work.Maybe you can to use the repo, and add some algorithms. write some code to test, then build a so file, and push to device.

Then you can add you code to this repo,build with jni.

BruceWind commented 5 years ago

There is a great article, C++使用AES+Base64算法对文本进行加密,but the algoritm is AES128,isnt 256。

VincentChen1212 commented 5 years ago

Hi,

Thanks for your helping. My Business Model is using AES256/CBC/PKCS7Padding, And I must use kotlin-native platform to build my project, it only support c (don't support c++), so I am so sad to find no suitable project (I don't understand c/c++ )

Thanks You VERY VERY VERY Much

BruceWind commented 5 years ago

I think, no kotlin-native in Android. Only "Java call native" in Android. Java can call native interface,regardless C , C++ or Assembly language.
Do you know I mean?

BruceWind commented 5 years ago

I mean you can use extern "C" to call you C++ code. like this calling-c-dll-from-java.

VincentChen1212 commented 5 years ago

Hi,

Thanks for your helping. My present situation : already create base64/sha/hmac using cinterop in kotlin-native project, now aes256 dosen't implement, but no suitable AES256/CBC/PKCS7Padding using c to reference.

Thanks You very much

BruceWind commented 5 years ago

okay, this week, i dont have a lot of work, maybe the repo will go ahead a little.

VincentChen1212 commented 5 years ago

Hi, It's a Good news for me. Thanks for your helping.

My Test Data is:
val data = "Discover interesting projects and people to populate your personal news feed"
val key = "XENT95ZAYCPH2CLFT7M2Y3WEWKB846B8"
val iv = "B3LCLM7CMXLY3ZAF"

The resule is:
JapXrfLPtd5bAkc69VtkeNlUeE/pgYdszgSQoqrDZEmg3GkA6wYx9+JaAtzNRg2ConKHmHtG/gCtNwpyO62OO+Jj+HnsxQwtvm8qkP2hpRI=

You are really my HERO

Thanks you very much

BruceWind commented 5 years ago

I think, maybe you are finding a wrong direction.

Java only provides PKCS#5 padding, but it is the same as PKCS#7 padding. See this question on Crypto.SE:

What is the difference between PKCS#5 padding and PKCS#7 padding

They are interchangeable for the common block ciphers like AES and DES. And such as AES&DES algorithm in cnblogs.

Then, I wrote a class to test.

import android.util.Base64;

import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESTest
{

    private static String KEY_AES = "D(G+KbPeShVmYq3t";
    public static String encrypt7(String value) {
        try {
            byte[] key = KEY_AES.getBytes("UTF-8");
            byte[] ivs = KEY_AES.getBytes("UTF-8");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            AlgorithmParameterSpec paramSpec = new IvParameterSpec(ivs);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, paramSpec);
            return Base64.encodeToString(cipher.doFinal(value.getBytes("UTF-8")), Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String encrypt5(String value) {
        try {
            byte[] key = KEY_AES.getBytes("UTF-8");
            byte[] ivs = KEY_AES.getBytes("UTF-8");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            AlgorithmParameterSpec paramSpec = new IvParameterSpec(ivs);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, paramSpec);
            return Base64.encodeToString(cipher.doFinal(value.getBytes("UTF-8")), Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

The result of two function is equal.

Look this: struct padding in crypto++ doc. I think, Crypto++ doesn't support PKCS7Padding.

VincentChen1212 commented 5 years ago

Hi, Thanks for your helping. I don't understand about C language, so if c only support pkcs5, it is ok.

My test data is use java & C#, my coworker seem also use pkcs5 by java.

You are truly my savior. I Really need C Code.

Thanks for your helping.

VincentChen1212 commented 5 years ago

Hi,

I Try my best to search on line I found some pages https://www.cnblogs.com/cqvoip/p/8078790.html http://www.longdw.com/aes-256-cbc-c-android-pkcs5padding/?utm_source=tuicool&utm_medium=referral

So I try to Modify a little

I Add 4 function

a) aes256_encrypt_cbc_mdy (modify len for original function aes256_encrypt_cbc)
b) aes256_decrypt_cbc_mdy(modify len for original function aes256_decrypt_cbc)
c) aes256_encrypt_cbc_pkcs
d) aes256_decrypt_cbc_pkcs

c) and d) is for java to use

but now if in the c code by 『var padding=0』---> Only for I Guess the result will error

val data = "Discover interesting projects and people to populate your personal news feed"
val key = "XENT95ZAYCPH2CLFT7M2Y3WEWKB846B8"
val iv = "B3LCLM7CMXLY3ZAF"

Java:JapXrfLPtd5bAkc69VtkeNlUeE/pgYdszgSQoqrDZEmg3GkA6wYx9+JaAtzNRg2ConKHmHtG/gCtNwpyO62OO+Jj+HnsxQwtvm8qkP2hpRI=

Error Enc:JapXrfLPtd5bAkc69VtkeNlUeE/pgYdszgSQoqrDZEmg3Gk=
Error Dec:Discover interesting projects an
=======================================================

If My data append "1" in the front
val data = "1Discover interesting projects and people to populate your personal news feed"

Java:wgH+atRi3VAbSLqC91TJ5fcKju7fzh2cOeZxopxeKPBb22zol6rlhjZewZKlJnzsgBdVzkSsu4xXZeEuhhUjK2e7eJGYE6AN4rFhJXlxXpo=

Correct Enc:wgH+atRi3VAbSLqC91TJ5fcKju7fzh2cOeZxopxeKPBb22zol6rlhjZewZKlJnzsgBdVzkSsu4xXZeEuhhUjK2e7eJGYE6AN4rFhJXlxXpo=
Correct Dec:1Discover interesting projects and people to populate your personal news feed

Could you please help me to find where is error.

Here is partial code

void aes256_encrypt_cbc_mdy(aes256_context *ctx, uint8_t *in, int in_len, uint8_t *iv, uint8_t *out)
{
    uint8_t i, j, rcon;
    uint8_t buf[16],iv_change[16];
//  int size = strlen(in) / 16; /* Vincent Modify */
    int size = in_len / 16;

    for(j = 0; j < size; j++ )
    {
        memcpy(buf, in + j * 16, 16 );
        if(j == 0)
        {
            aes_cbc(buf,iv);
            aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
            for(i = 1, rcon = 1; i < 14; ++i)
            {
                aes_subBytes(buf);
                aes_shiftRows(buf);
                aes_mixColumns(buf);
                if( i & 1 ) aes_addRoundKey(buf, &ctx->key[16]);
                else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
            }
            aes_subBytes(buf);
            aes_shiftRows(buf);
            aes_expandEncKey(ctx->key, &rcon);
            aes_addRoundKey(buf, ctx->key);

            memcpy(out + j * 16, buf, 16);
            memcpy(iv_change,buf,16);
        }
        else
        {
            aes_cbc(buf,iv_change);
            aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
            for(i = 1, rcon = 1; i < 14; ++i)
            {
                aes_subBytes(buf);
                aes_shiftRows(buf);
                aes_mixColumns(buf);
                if( i & 1 ) aes_addRoundKey(buf, &ctx->key[16]);
                else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
            }
            aes_subBytes(buf);
            aes_shiftRows(buf);
            aes_expandEncKey(ctx->key, &rcon);
            aes_addRoundKey(buf, ctx->key);

            memcpy(out + j * 16, buf, 16);
            memcpy(iv_change,buf,16);
        }
    }
}/*aes256_encrypt_cbc*/

void aes256_decrypt_cbc_mdy(aes256_context *ctx, uint8_t *in, int in_len, uint8_t *iv, uint8_t *out)
{
    uint8_t i, j, rcon;
    uint8_t buf[16], iv_change_1[16], iv_change_2[16];
    int size = in_len / 16; /* Vincent Add */

//  for(j = 0; j < 240; j++ ) /* Vincent Modify */
    for(j = 0; j < size; j++ )
    {
        memcpy(buf, in + j * 16, 16 );
        if(j == 0)
        {
            memcpy(iv_change_1,buf,16);
            aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
            aes_shiftRows_inv(buf);
            aes_subBytes_inv(buf);

            for (i = 14, rcon = 0x80; --i;)
            {
                if( ( i & 1 ) )
                {
                    aes_expandDecKey(ctx->key, &rcon);
                    aes_addRoundKey(buf, &ctx->key[16]);
                }
                else aes_addRoundKey(buf, ctx->key);
                aes_mixColumns_inv(buf);
                aes_shiftRows_inv(buf);
                aes_subBytes_inv(buf);
            }
            aes_addRoundKey(buf, ctx->key);
            aes_cbc(buf,iv);

            memcpy(out + j * 16, buf, 16);
            memcpy(iv_change_2,iv_change_1,16);
        }
        else
        {
            memcpy(iv_change_1,buf,16);
            aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
            aes_shiftRows_inv(buf);
            aes_subBytes_inv(buf);

            for (i = 14, rcon = 0x80; --i;)
            {
                if( ( i & 1 ) )
                {
                    aes_expandDecKey(ctx->key, &rcon);
                    aes_addRoundKey(buf, &ctx->key[16]);
                }
                else aes_addRoundKey(buf, ctx->key);
                aes_mixColumns_inv(buf);
                aes_shiftRows_inv(buf);
                aes_subBytes_inv(buf);
            }
            aes_addRoundKey(buf, ctx->key);
            aes_cbc(buf,iv_change_2);

            memcpy(out + j * 16, buf, 16);
            memcpy(iv_change_2,iv_change_1,16);
        }
    }

}/*aes256_decrypt_cbc*/

void aes256_encrypt_cbc_pkcs(uint8_t *key, uint8_t *src, int srcLen, uint8_t *iv, uint8_t *out)
{
    //PKCS5 PADDING
    int quotient = srcLen / AES_BLOCK_SIZE;
    int mod = srcLen % AES_BLOCK_SIZE;
    int blockCount = quotient + 1;

    int padding = AES_BLOCK_SIZE - mod;
    unsigned char *in = (char *)malloc(AES_BLOCK_SIZE*blockCount);
    memset(in, padding, AES_BLOCK_SIZE*blockCount);
    memcpy(in, src, srcLen);

    aes256_context ctx;
    aes256_init(&ctx, key);

    aes256_encrypt_cbc_mdy(&ctx, in, AES_BLOCK_SIZE*blockCount, iv, out);
}/*aes256_encrypt_cbc_pkcs*/

void aes256_decrypt_cbc_pkcs(uint8_t *key, uint8_t *src, int srcLen, uint8_t *iv, uint8_t *out)
{
    aes256_context ctx;
    aes256_init(&ctx, key);

    aes256_decrypt_cbc_mdy(&ctx, src, srcLen, iv, out);

    // Unpadding
    int padding = out[srcLen - 1];
    int dlen = srcLen - padding;

    // dst
    if (dlen <= 0){
        free(out);
        return;
    }
    unsigned char *dst = (unsigned char *)malloc(dlen);
    memset(dst, 0x00, dlen);
    memcpy(dst, out, dlen);
    free(out);
    out = dst;
}/*aes256_decrypt_cbc_pkcs*/

Thanks for your helping.

BruceWind commented 5 years ago

Obviously,length of Discover interesting projects an is 32, 32 same to 16 * 2. Perhaps, "length" and some loop have mistakes.

If you ask about your aes algorithm, this isn't a question and answer platform.Pls go to Stackoverflow. Im Sorry.

BruceWind commented 3 years ago

sorry, AES no longer support, I have pushed code that use chacah20 instead of AES. https://github.com/BruceWind/AESJniEncrypt/pull/40

PeterleSoftwares commented 3 years ago

There is a great article, C++使用AES+Base64算法对文本进行加密,but the algoritm is AES128,isnt 256。

Thanks to mr. BruceWind!!! He saved my life with this article referral!!!

BruceWind commented 3 years ago

@PeterleSoftwares You are welcome. Very appreciate that it helped you.