最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - C - Encrypt and decrypt a string with AES - Stack Overflow

programmeradmin1浏览0评论

I'm trying to understand how to use this c library (tiny-AES-c). As a web developer, I'm looking to get an equivalent C code for this JS fiddle.

The JS code is straightforward:

// Encrypt
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123');


console.log("Encrypted: " + ciphertext.toString());

// Decrypt
var bytes  = CryptoJS.AES.decrypt(ciphertext.toString(), 'secret key 123');
var plaintext = bytes.toString(CryptoJS.enc.Utf8);

console.log("Decrypted: " + plaintext);

Given a message to encrypt and a secret, the code generates the encrypted data and transform the results to a string.


My C code:

int main()
{
    uint8_t in[]  = "my message";
    uint8_t key[] =  "secret key 123";

    struct AES_ctx ctx;

    AES_init_ctx(&ctx, key);
    printf("ORIG: %s",(char*) in);
    
    // Encrypt
    AES_ECB_encrypt(&ctx, in);
    printf("\nENC: %s",(char*) in);
 
    // Decrypt
    AES_ECB_decrypt(&ctx, in);
    printf("\nDEC: %s",(char*) in);

    return 0;
}

The output:

ORIG: my message
ENC: ̤�+��5<n]EYK�ظ/����
DEC: my message%  

I understand that I shouldn't try to print the result as a string, but couldn't figure out how to get similar (to the JS) results, using the tiny-AES-c API, plus when I tried using longer messages I got strange results, leading me to think I'm using this library the wrong way.

Q: What would be the C code equivalent to the above JS?

I'm trying to understand how to use this c library (tiny-AES-c). As a web developer, I'm looking to get an equivalent C code for this JS fiddle.

The JS code is straightforward:

// Encrypt
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123');


console.log("Encrypted: " + ciphertext.toString());

// Decrypt
var bytes  = CryptoJS.AES.decrypt(ciphertext.toString(), 'secret key 123');
var plaintext = bytes.toString(CryptoJS.enc.Utf8);

console.log("Decrypted: " + plaintext);

Given a message to encrypt and a secret, the code generates the encrypted data and transform the results to a string.


My C code:

int main()
{
    uint8_t in[]  = "my message";
    uint8_t key[] =  "secret key 123";

    struct AES_ctx ctx;

    AES_init_ctx(&ctx, key);
    printf("ORIG: %s",(char*) in);
    
    // Encrypt
    AES_ECB_encrypt(&ctx, in);
    printf("\nENC: %s",(char*) in);
 
    // Decrypt
    AES_ECB_decrypt(&ctx, in);
    printf("\nDEC: %s",(char*) in);

    return 0;
}

The output:

ORIG: my message
ENC: ̤�+��5<n]EYK�ظ/����
DEC: my message%  

I understand that I shouldn't try to print the result as a string, but couldn't figure out how to get similar (to the JS) results, using the tiny-AES-c API, plus when I tried using longer messages I got strange results, leading me to think I'm using this library the wrong way.

Q: What would be the C code equivalent to the above JS?

Share Improve this question edited Dec 13, 2023 at 12:48 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked May 9, 2018 at 13:32 Roni GadotRoni Gadot 4873 gold badges19 silver badges31 bronze badges 7
  • You want to encrypt a string using AES ? is that what the whole question is ? (I am sorry unable to understand ) – Muhammad Salman Commented May 9, 2018 at 13:50
  • No, the question is library specific. thank you. – Roni Gadot Commented May 9, 2018 at 14:30
  • I see , Oh well I am not aware of that library – Muhammad Salman Commented May 9, 2018 at 14:31
  • If you are looking for good security use a well vetted implementation such as provided by the language or platform provider. While the results are the same there may be timing flaws or other side-channel vulnerabilities. Also the lack of padding support for ECB and CBC modes is problematic and null padding is not a good solution. Many solutions use processor AES instructions which are orders of magnitude faster. – zaph Commented May 10, 2018 at 8:53
  • Thanks @zaph, the point is I'm using this code in a WebAssembly model, using 3rd party libs are a headache. I'm trying to extract the necessary code only. – Roni Gadot Commented May 10, 2018 at 11:17
 |  Show 2 more ments

3 Answers 3

Reset to default 1

I am the original author of the AES library you reference.

When using ECB and CBC modes of operation, you need to make sure your key, iv and the input/output blocks are all 16 bytes long. You also need to decide on which padding scheme you want to use.

You can use CTR-mode to avoid padding and stop worrying about block-sizes. This generally makes the AES algorithm much easier to use as there are fewer edge-cases to handle.

BTW this is also stated in the project README:

No padding is provided so for CBC and ECB all buffers should be mutiples of 16 bytes. For padding PKCS7 is remendable.

ECB mode is considered unsafe for most uses and is not implemented in streaming mode. If you need this mode, call the function for every block of 16 bytes you need encrypted. See wikipedia's article on ECB for more details.

EDIT:

If you extend your arrays so that they are 16 bytes long and zero-pad them (or alternatively, declare them static so they will be zero-initialized automatically), I think it should work for you :)

As @Morten Jensen suggested, you can use the CTR-mode IE:AES_CTR_xcrypt_buffer

int main()
{
    uint8_t key[] = "secret key 123";
    uint8_t in[]  = "my message";
    uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };

    printf("Length: %lu",strlen((char*)in));

    struct AES_ctx ctx;
    AES_init_ctx_iv(&ctx, key, iv);
    AES_CTR_xcrypt_buffer(&ctx, in, strlen((char*)in));
    printf("\nENC: %s",(char*) in); // don't use this string as an input

    AES_init_ctx_iv(&ctx, key, iv);
    AES_CTR_xcrypt_buffer(&ctx, in, strlen((char*)in));
    printf("\nDEC: %s",(char*) in);
    return 0;
}

Remember, printing the encrypted data is wrong, you should go over the output and convert it to base64 if you want to match your JS example.

uint8_t in[16]  = "my message";

your buffer needs to be a multiple of 16.

发布评论

评论列表(0)

  1. 暂无评论