public
Last active

A simple example of using AES encryption in Java and C.

  • Download Gist
AES.c
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
/*
* MCrypt API available online:
* http://linux.die.net/man/3/mcrypt
*/
#include <mcrypt.h>
 
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
 
int encrypt(
void* buffer,
int buffer_len, /* Because the plaintext could include null bytes*/
char* IV,
char* key,
int key_len
){
MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
int blocksize = mcrypt_enc_get_block_size(td);
if( buffer_len % blocksize != 0 ){return 1;}
 
mcrypt_generic_init(td, key, key_len, IV);
mcrypt_generic(td, buffer, buffer_len);
mcrypt_generic_deinit (td);
mcrypt_module_close(td);
return 0;
}
 
int decrypt(
void* buffer,
int buffer_len,
char* IV,
char* key,
int key_len
){
MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
int blocksize = mcrypt_enc_get_block_size(td);
if( buffer_len % blocksize != 0 ){return 1;}
mcrypt_generic_init(td, key, key_len, IV);
mdecrypt_generic(td, buffer, buffer_len);
mcrypt_generic_deinit (td);
mcrypt_module_close(td);
return 0;
}
 
void display(char* ciphertext, int len){
int v;
for (v=0; v<len; v++){
printf("%d ", ciphertext[v]);
}
printf("\n");
}
 
int main()
{
MCRYPT td, td2;
char * plaintext = "test text 123";
char* IV = "AAAAAAAAAAAAAAAA";
char *key = "0123456789abcdef";
int keysize = 16; /* 128 bits */
char* buffer;
int buffer_len = 16;
 
buffer = calloc(1, buffer_len);
strncpy(buffer, plaintext, buffer_len);
 
printf("==C==\n");
printf("plain: %s\n", plaintext);
encrypt(buffer, buffer_len, IV, key, keysize);
printf("cipher: "); display(buffer , buffer_len);
decrypt(buffer, buffer_len, IV, key, keysize);
printf("decrypt: %s\n", buffer);
return 0;
}
AES.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
public class AES {
static String IV = "AAAAAAAAAAAAAAAA";
static String plaintext = "test text 123\0\0\0"; /*Note null padding*/
static String encryptionKey = "0123456789abcdef";
public static void main(String [] args) {
try {
System.out.println("==Java==");
System.out.println("plain: " + plaintext);
 
byte[] cipher = encrypt(plaintext, encryptionKey);
 
System.out.print("cipher: ");
for (int i=0; i<cipher.length; i++)
System.out.print(new Integer(cipher[i])+" ");
System.out.println("");
 
String decrypted = decrypt(cipher, encryptionKey);
 
System.out.println("decrypt: " + decrypted);
 
} catch (Exception e) {
e.printStackTrace();
}
}
 
public static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(plainText.getBytes("UTF-8"));
}
 
public static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return new String(cipher.doFinal(cipherText),"UTF-8");
}
}

Defining full 8-bit byte data like the key and IV as ASCII strings, hoping they get magically converted by the compiler, will lead to unexpected results. Secondly, the buffer, when decrypted, certainly won't have a 0 byte at the end, so printing it as is, even if it is printable, will get another unexpected result.

The reason I'm writing this contrary to simply patching is people with homework will find this page and learn nothing from it otherwise.

thanx! just what i need

good work.... thanks, what about Aes serpant, Aes twofish method..

Thank you so much for sharing this! :D

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.