https://gist.github.com/thomasdarimont/fae409eaae2abcf83bd6633b961e7f00
这是aes加密解密互通的代码,php和java的,一种语言加密,另一种可以解密。
修改的地方:省略了向量的输入,太麻烦。读者可自行修改此代码,使得加密更加健壮。
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 $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); } }