Skip to content

Instantly share code, notes, and snippets.

@grisu48
Last active April 28, 2017 08:10
Show Gist options
  • Save grisu48/dd18ccbda27c4fbe7a6844d72027a68c to your computer and use it in GitHub Desktop.
Save grisu48/dd18ccbda27c4fbe7a6844d72027a68c to your computer and use it in GitHub Desktop.
AES Stream implementations, Based on https://gist.github.com/bricef/2436364
/*
* Compile with -lmcrypt
*/
#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;
}
package ssl;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AES encryption stream
*
* @author phoenix
*
*/
public class AESStream {
/** Initialisation vector */
private byte[] iv = new byte[16];
/** Encryption key */
private byte[] key = null;
/** Used cipher suide */
private Cipher cipher;
/** Static secure random generator for IV */
private static final SecureRandom random = new SecureRandom();
/**
* Create {@link AESStream} instance
*
* @param padding
* true if padding is enabled
*/
public AESStream(final boolean padding) {
this.key = null;
this.iv = null;
try {
if (padding)
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
else
cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Encryption algorithm not supported", e);
} catch (NoSuchPaddingException e) {
throw new RuntimeException("Padding algoritm not supported", e);
}
}
/**
* Create default {@link AESStream} instance with enabled padding
*/
public AESStream() {
this(true);
}
/**
*
* @param key
* UTF-8 encoded encryption key
*/
public AESStream(final String key, final boolean padding) {
this(padding);
try {
setKey(key.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported UTF-8 encoding", e);
}
}
/**
*
* @param key
* UTF-8 encoded encryption key
*/
public AESStream(final byte[] key, final boolean padding) {
this(padding);
setKey(key);
}
/**
* Set the key for the encryption. The key size must be 16 byte (AES128) or
* 32 byte (AES256)
*
* @param key
* to be set
*/
public void setKey(byte[] key) {
if (key.length == 16 || key.length == 32)
this.key = key;
else
throw new IllegalArgumentException("Invalid key size");
}
/**
* @return the initialisation vector for AES
*/
public byte[] getIV() {
return iv;
}
/**
* Set the initialisation vector for AES
*
* @param iv
* 16 byte long initialisation vector
*/
public void setIV(byte[] iv) {
if (iv.length < 16)
throw new IndexOutOfBoundsException("Initialisation vector smaller than 16 bytes");
this.iv = new byte[16];
for (int i = 0; i < 16; i++)
this.iv[i] = iv[i];
}
public void setKey(final String key) {
try {
setKey(key.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported UTF-8 encoding", e);
}
}
public byte[] encrypt(final String plainText) {
try {
byte[] input = plainText.getBytes("UTF-8");
return encrypt(input);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported encoding", e);
}
}
public byte[] encrypt(final byte[] buffer) {
final SecretKeySpec key = new SecretKeySpec(this.key, "AES");
synchronized (this.cipher) {
try {
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(buffer);
} catch (InvalidKeyException e) {
throw new RuntimeException("Invalid key", e);
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException("Invalid algorithm", e);
} catch (IllegalBlockSizeException e) {
throw new RuntimeException("Illegal block size", e);
} catch (BadPaddingException e) {
throw new RuntimeException("Bad padding", e);
}
}
}
public String decryptStr(byte[] cipherText) {
final byte[] buf = decrypt(cipherText);
try {
return new String(buf, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported encoding", e);
}
}
public String decryptStr(final String cipherText) {
try {
return decryptStr(cipherText.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported encoding", e);
}
}
public byte[] decrypt(final String cipherText) {
try {
return decrypt(cipherText.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported encoding", e);
}
}
public byte[] decrypt(byte[] cipherText) {
if (cipherText.length % 16 != 0)
throw new RuntimeException("Input block size wrong");
synchronized (this.cipher) {
final SecretKeySpec key = new SecretKeySpec(this.key, "AES");
try {
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
byte[] buffer = cipher.doFinal(cipherText);
return buffer;
} catch (InvalidKeyException e) {
throw new RuntimeException("Invalid key", e);
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException("Invalid algorithm", e);
} catch (IllegalBlockSizeException e) {
throw new RuntimeException("Illegal block size", e);
} catch (BadPaddingException e) {
throw new RuntimeException("Bad padding", e);
}
}
}
}
@grisu48
Copy link
Author

grisu48 commented Apr 27, 2017

This is a temporary push and should not be used by anyone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment