代码主要来源如下,但是注意做了修改:
https://gist.github.com/thomasdarimont/fae409eaae2abcf83bd6633b961e7f00
这是aes
加密解密互通的代码,php和java的,一种语言加密,另一种可以解密。
修改的地方:省略了向量的输入,太麻烦。读者可自行修改此代码,使得加密更加健壮。
php代码:
class="php" name="code">
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 $data - data to encrypt
* @return encrypted data in base64 encoding with iv attached at end after a :
*/
public static function encrypt( $key, $data )
{
$iv = substr( $key, 0, 5 );
$iv = str_pad( $iv, 16, '0' );
$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
*/
public 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;
}
}
java代码
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
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 data) {
String iv = key.substring(0,5);
iv += "00000000000";
try {
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
SecretKeySpec secretKey = new SecretKeySpec(fixKey(key).getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance(AesCrypto.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("UTF-8"));
return encryptedDataInBase64 + ":" + ivInBase64;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static String fixKey(String key) {
if (key.length() < AesCrypto.CIPHER_KEY_LEN) {
int numPad = AesCrypto.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() > AesCrypto.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("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance(AesCrypto.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 = "GNwmNkJ2UZDwhqJ2"; // 128 bit key
String plain_text = "input张 三你好!!";
String encrypted = encrypt(key, plain_text);
System.out.println(encrypted);
String decrypt = decrypt(key, encrypted);
System.out.println(decrypt);
}
}