Skip to content

Instantly share code, notes, and snippets.

@thomasdarimont
Last active November 29, 2024 09:32
Show Gist options
  • Save thomasdarimont/fae409eaae2abcf83bd6633b961e7f00 to your computer and use it in GitHub Desktop.
Save thomasdarimont/fae409eaae2abcf83bd6633b961e7f00 to your computer and use it in GitHub Desktop.
Example for 128bit AES with Java and PHP
<?php
class AesCipher {
private const OPENSSL_CIPHER_NAME = "aes-128-cbc";
private const CIPHER_KEY_LEN = 16; //128 bits
private static function fixKey($key) {
if (strlen($key) < AesCipher::CIPHER_KEY_LEN) {
//0 pad to len 16
return str_pad("$key", AesCipher::CIPHER_KEY_LEN, "0");
}
if (strlen($key) > AesCipher::CIPHER_KEY_LEN) {
//truncate to 16 bytes
return substr($key, 0, AesCipher::CIPHER_KEY_LEN);
}
return $key;
}
/**
* Encrypt data using AES Cipher (CBC) with 128 bit key
*
* @param type $key - key to use should be 16 bytes long (128 bits)
* @param type $iv - initialization vector
* @param type $data - data to encrypt
* @return encrypted data in base64 encoding with iv attached at end after a :
*/
static function encrypt($key, $iv, $data) {
$encodedEncryptedData = base64_encode(openssl_encrypt($data, AesCipher::OPENSSL_CIPHER_NAME, AesCipher::fixKey($key), OPENSSL_RAW_DATA, $iv));
$encodedIV = base64_encode($iv);
$encryptedPayload = $encodedEncryptedData.":".$encodedIV;
return $encryptedPayload;
}
/**
* Decrypt data using AES Cipher (CBC) with 128 bit key
*
* @param type $key - key to use should be 16 bytes long (128 bits)
* @param type $data - data to be decrypted in base64 encoding with iv attached at the end after a :
* @return decrypted data
*/
static function decrypt($key, $data) {
$parts = explode(':', $data); //Separate Encrypted data from iv.
$encrypted = $parts[0];
$iv = $parts[1];
$decryptedData = openssl_decrypt(base64_decode($encrypted), AesCipher::OPENSSL_CIPHER_NAME, AesCipher::fixKey($key), OPENSSL_RAW_DATA, base64_decode($iv));
return $decryptedData;
}
};
$decrypted = AesCipher::decrypt('0123456789abcdef', 'G0a6cK+sxBkSwyCjcG4efA==:YWJjZGVmOTg3NjU0MzIxMA==');
var_dump($decrypted);
?>
package de.tdlabs.training.crypto;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class AesCrypto {
private static String CIPHER_NAME = "AES/CBC/PKCS5PADDING";
private static int CIPHER_KEY_LEN = 16; //128 bits
/**
* Encrypt data using AES Cipher (CBC) with 128 bit key
*
* @param key - key to use should be 16 bytes long (128 bits)
* @param iv - initialization vector
* @param data - data to encrypt
* @return encryptedData data in base64 encoding with iv attached at end after a :
*/
public static String encrypt(String key, String iv, String data) {
try {
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
SecretKeySpec secretKey = new SecretKeySpec(fixKey(key).getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance(CIPHER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
byte[] encryptedData = cipher.doFinal((data.getBytes()));
String encryptedDataInBase64 = Base64.getEncoder().encodeToString(encryptedData);
String ivInBase64 = Base64.getEncoder().encodeToString(iv.getBytes(StandardCharsets.UTF_8));
return encryptedDataInBase64 + ":" + ivInBase64;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static String fixKey(String key) {
if (key.length() < CIPHER_KEY_LEN) {
int numPad = CIPHER_KEY_LEN - key.length();
for (int i = 0; i < numPad; i++) {
key += "0"; //0 pad to len 16 bytes
}
return key;
}
if (key.length() > CIPHER_KEY_LEN) {
return key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
}
return key;
}
/**
* Decrypt data using AES Cipher (CBC) with 128 bit key
*
* @param key - key to use should be 16 bytes long (128 bits)
* @param data - encrypted data with iv at the end separate by :
* @return decrypted data string
*/
public static String decrypt(String key, String data) {
try {
String[] parts = data.split(":");
IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(parts[1]));
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance(CIPHER_NAME);
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] decodedEncryptedData = Base64.getDecoder().decode(parts[0]);
byte[] original = cipher.doFinal(decodedEncryptedData);
return new String(original);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static void main(String[] args) {
String key = "0123456789abcdef"; // 128 bit key
String initVector = "abcdef9876543210"; // 16 bytes IV, it is recommended to use a different random IV for every message!
String plain_text = "plain text";
String encrypted = encrypt(key, initVector, plain_text);
System.out.println(encrypted);
String decrypt = decrypt(key, encrypted);
System.out.println(decrypt);
}
}
@raksrivastava
Copy link

raksrivastava commented Feb 2, 2018

Please correct this.I think $str is written by mistake.
return substr($str, 0, AesCipher::CIPHER_KEY_LEN);

private static function fixKey($key) {

    if (strlen($key) < AesCipher::CIPHER_KEY_LEN) {
        //0 pad to len 16
        return str_pad("$key", AesCipher::CIPHER_KEY_LEN, "0"); 
    }
    
    if (strlen($key) > AesCipher::CIPHER_KEY_LEN) {
        //truncate to 16 bytes
        return substr($str, 0, AesCipher::CIPHER_KEY_LEN); 
    }
    return $key;
}

@leonurium
Copy link

can you help make this class encrypt decrypt in php?

import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class d
{
  static char[] a = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102 };
  private String b = "Lvx3Spqh6lRefVJK";
  private IvParameterSpec c = new IvParameterSpec(this.b.getBytes());
  private SecretKeySpec d;
  private Cipher e;
  private String f = "PsAJzu4Ks91YWq4F";
  
  public d()
  {
    try
    {
      this.e = Cipher.getInstance("AES/CBC/NoPadding");
      return;
    }
    catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
    {
      localNoSuchAlgorithmException.printStackTrace();
      return;
    }
    catch (NoSuchPaddingException localNoSuchPaddingException)
    {
      localNoSuchPaddingException.printStackTrace();
    }
  }
  
  public static String a(byte[] paramArrayOfByte)
  {
    char[] arrayOfChar = new char[paramArrayOfByte.length * 2];
    int i = 0;
    while (i < paramArrayOfByte.length)
    {
      arrayOfChar[(i * 2)] = a[((paramArrayOfByte[i] & 0xF0) >>> 4)];
      arrayOfChar[(i * 2 + 1)] = a[(paramArrayOfByte[i] & 0xF)];
      i += 1;
    }
    return new String(arrayOfChar);
  }
  
  public static byte[] a(String paramString)
  {
    Object localObject = null;
    if (paramString == null) {}
    while (paramString.length() < 2) {
      return (byte[])localObject;
    }
    int j = paramString.length() / 2;
    byte[] arrayOfByte = new byte[j];
    int i = 0;
    for (;;)
    {
      localObject = arrayOfByte;
      if (i >= j) {
        break;
      }
      arrayOfByte[i] = ((byte)Integer.parseInt(paramString.substring(i * 2, i * 2 + 2), 16));
      i += 1;
    }
  }
  
  private static String b(String paramString)
  {
    int j = paramString.length();
    int i = 0;
    while (i < 16 - j % 16)
    {
      paramString = paramString + '\000';
      i += 1;
    }
    return paramString;
  }
  
  public byte[] a(String paramString1, String paramString2)
  {
    if ((paramString2 == null) || (paramString2.length() == 0)) {}
    for (this.d = new SecretKeySpec(this.f.getBytes(), "AES"); (paramString1 == null) || (paramString1.length() == 0); this.d = new SecretKeySpec(paramString2.substring(0, 16).getBytes(), "AES")) {
      throw new Exception("Empty string");
    }
    try
    {
      this.e.init(1, this.d, this.c);
      paramString1 = this.e.doFinal(b(paramString1).getBytes());
      return paramString1;
    }
    catch (Exception paramString1)
    {
      throw new Exception("[encrypt] " + paramString1.getMessage());
    }
  }
  
  public byte[] b(String paramString1, String paramString2)
  {
    if ((paramString2 == null) || (paramString2.length() == 0)) {}
    for (this.d = new SecretKeySpec(this.f.getBytes(), "AES"); (paramString1 == null) || (paramString1.length() == 0); this.d = new SecretKeySpec(paramString2.substring(0, 16).getBytes(), "AES")) {
      throw new Exception("Empty string");
    }
    for (;;)
    {
      int j;
      int i;
      try
      {
        this.e.init(2, this.d, this.c);
        paramString1 = this.e.doFinal(a(paramString1));
        if (paramString1.length <= 0) {
          break label181;
        }
        j = paramString1.length;
        i = 0;
        j -= 1;
      }
      catch (Exception paramString1)
      {
        throw new Exception("[decrypt] " + paramString1.getMessage());
      }
      if (i > 0)
      {
        paramString2 = new byte[paramString1.length - i];
        System.arraycopy(paramString1, 0, paramString2, 0, paramString1.length - i);
        return paramString2;
      }
      label181:
      return paramString1;
      while (j >= 0)
      {
        int k = i;
        if (paramString1[j] == 0) {
          k = i + 1;
        }
        j -= 1;
        i = k;
      }
    }
  }
}

@b1ghawk
Copy link

b1ghawk commented Sep 28, 2018

I will try it out, thx ^ ^

@princealirehman1
Copy link

Is there a same sample for swift ?

@nicolasbui
Copy link

Work perfectly for me. Thank you !

@christophernarciso
Copy link

Thank you so much.

@nandaks
Copy link

nandaks commented Mar 30, 2020

I want to implement the same encryption and decryption in angular. Please help me.

@nicolasbui
Copy link

I want to implement the same encryption and decryption in angular. Please help me.

There are plenty AES for JS out there, but, I would not recommend using it on client side ... because you will expose your key...

@sandip-maji
Copy link

sandip-maji commented Oct 19, 2020

PHP Code :

$iv = "8147829559990027";
$key = "SANDIP0000000000";
$data = "sandip";
$encodedEncryptedData = base64_encode(openssl_encrypt($data, "aes-256-cbc",$key, OPENSSL_RAW_DATA, $iv));
echo $encodedEncryptedData;

Output :

wbkrmlU2fFKhvSxd0f5wsA==

Java Code :

public class Posttouch {

private static String CIPHER_NAME = "AES/CBC/PKCS5PADDING";

public static void main(String args[]) {
	System.out.println("working");
	String key = "SANDIP0000000000";
	String iv = "8147829559990027";
	String data = "sandip";
	String encrypt = null;
	try {
		encrypt = encrypt(key, iv, data);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	System.out.println(encrypt);
}

public static String encrypt(String key, String iv, String data) {

	try {
		IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
		SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

		Cipher cipher = Cipher.getInstance(CIPHER_NAME);
		cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

		byte[] encryptedData = cipher.doFinal((data.getBytes()));

		String encryptedDataInBase64 = Base64.getEncoder().encodeToString(encryptedData);
		String ivInBase64 = Base64.getEncoder().encodeToString(iv.getBytes(StandardCharsets.UTF_8));

		return encryptedDataInBase64;

	} catch (Exception ex) {
		throw new RuntimeException(ex);
	}
}

}

Output :
afYoGd4LZfWBrQ3cgf61vQ==

What is the issue in java code? generating different encrypting string, please help

@kyfr59
Copy link

kyfr59 commented Nov 29, 2024

It works perfectly for me. Thank you very much Thomas !

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