Bei der symmetrischen Verschlüsselung teilen sich zwei Kommunikationspartner einen geheimen Schlüssel (Passwort). Die folgende einfache Javaklasse hilft dabei, die Ver- und Entschlüsselung durchzuführen.
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* Hilfsklasse für symmetrische Verschlüsselungen.
*
* @author Serhat Cinar
*/
public final class CryptionUtils {
/**
* Bezeichner AES.
*/
public static final String ALGO_AES = "AES";
/**
* Bezeichner DES.
*/
public static final String ALGO_DES = "DES";
/**
* Bezeichner Tripple-DES.
*/
public static final String ALGO_TRIPPLE_DES = "DESede";
/**
* Bezeichner Blowfish.
*/
public static final String ALGO_BLOWFISH = "Blowfish";
private CryptionUtils() {
}
/**
* Verschlüsselt die angegebenen Daten mit dem angegebenen Schlüssel.
*
* @param algorithm Ein Verschlüsselungsalgortihmus, z. B. "DES"
* @param secretKey Der Schlüssel
* @param rawData Zu verschlüsselnde Daten
* @return Verschlüsselte Daten
*/
public static final byte[] encryptSymmetric(final String algorithm, final byte[] secretKey, final byte[] rawData)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException {
final SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, algorithm);
final Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
return cipher.doFinal(rawData);
}
/**
* Verschlüsselt die angegebenen Daten mit dem angegebenen Schlüssel.
*
* @param algorithm Ein Verschlüsselungsalgortihmus, z. B. "DES"
* @param secretKeyHex Der Schlüssel als HEX-String
* @param rawData Zu verschlüsselnde Daten
* @return Verschlüsselte Daten
*/
public static final byte[] encryptSymmetric(final String algorithm, final String secretKeyHex, final String rawData)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, UnsupportedEncodingException {
final SecretKeySpec secretKeySpec = new SecretKeySpec(hexStringToByteArray(secretKeyHex), algorithm);
final Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
return cipher.doFinal(rawData.getBytes("UTF-8"));
}
/**
* Entschlüsselt die angegebenen Daten mit dem angegebenen Schlüssel.
*
* @param algorithm Ein Verschlüsselungsalgortihmus, z. B. "DES"
* @param secretKey Der Schlüssel
* @param encryptedData Verschlüsselte Daten
* @return Entschlüsselte Daten
*/
public static final byte[] decryptSymmetric(final String algorithm, final byte[] secretKey,
final byte[] encryptedData) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
final SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, algorithm);
final Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
return cipher.doFinal(encryptedData);
}
/**
* Entschlüsselt die angegebenen Daten mit dem angegebenen Schlüssel.
*
* @param algorithm Ein Verschlüsselungsalgortihmus, z. B. "DES"
* @param secretKeyHex Der Schlüssel als HEX-String
* @param encryptedDataHex Verschlüsselte Daten als HEX-String
* @return Entschlüsselte Daten
*/
public static final byte[] decryptSymmetric(final String algorithm, final String secretKeyHex,
final String encryptedDataHex) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
final SecretKeySpec secretKey = new SecretKeySpec(hexStringToByteArray(secretKeyHex), algorithm);
final Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(hexStringToByteArray(encryptedDataHex));
}
/**
* Erzeugt einen Schlüssel.
*
* @param algorithm Ein Verschlüsselungsalgortihmus, z. B. "DES"
* @param keylength Länge des Schlüssels
* @return Generierter Schlüssel
*/
public static final byte[] generateSecretKey(final String algorithm, final int keylength)
throws NoSuchAlgorithmException {
final KeyGenerator keygen = KeyGenerator.getInstance(algorithm);
keygen.init(keylength);
final SecretKey secretKey = keygen.generateKey();
return secretKey.getEncoded();
}
/**
* Wandelt einen HEX-String in einen Byte-Array um.
*
* @param s Ein HEX-String
* @return Bytes aus dem HEX-String
*/
public static final byte[] hexStringToByteArray(final String s) {
final int len = s.length();
final byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
}
return data;
}
private static final String HEXES = "0123456789ABCDEF";
/**
* Wandelt einen Byte-Array in einen HEX-String um.
*
* @param s Ein Byte-Array
* @return HEX-String des Byte-Arrays
*/
public static final String byteArrayToHexString(final byte[] raw) {
if (raw == null) {
return null;
}
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
public static final void main(final String argv[]) {
boolean printUsage = true;
if (argv != null && argv.length > 1) {
final String action = argv[0];
if ("keygen".equalsIgnoreCase(action) && argv.length >= 3) {
final String algo = argv[1];
int keyLength;
try {
keyLength = Integer.parseInt(argv[2]);
System.out.println(byteArrayToHexString(generateSecretKey(algo, keyLength)));
printUsage = false;
} catch (final Exception e) {
e.printStackTrace();
}
} else if ("encrypt".equalsIgnoreCase(action) && argv.length >= 4) {
final String algo = argv[1];
final String key = argv[2];
final String data = argv[3];
try {
System.out.println(byteArrayToHexString(encryptSymmetric(algo, key, data)));
printUsage = false;
} catch (final Exception e) {
e.printStackTrace();
}
} else if ("decrypt".equalsIgnoreCase(action)) {
final String algo = argv[1];
final String key = argv[2];
final String data = argv[3];
try {
System.out.println(new String(decryptSymmetric(algo, key, data), "UTF-8"));
printUsage = false;
} catch (final Exception e) {
e.printStackTrace();
}
}
}
if (printUsage) {
printUsage();
System.exit(0);
}
}
private static void printUsage() {
System.out.println("Usage: <action> <parameter>");
System.out.println(" Actions:");
System.out.println(" keygen - generates a key");
System.out.println(" parameters: <algorithm> <keylength>");
System.out.println(" encrypt - encrypts a text");
System.out.println(" parameters: <algorithm> <hexsecretkey> <text>");
System.out.println(" decrypt - decrypts a hex encoded secret");
System.out.println(" parameters: <algorithm> <hexsecretkey> <hexdata>");
System.out.println(" Algorithm should be one of \"" + ALGO_AES + "\", \"" + ALGO_BLOWFISH + "\", \""
+ ALGO_DES + "\", \"" + ALGO_TRIPPLE_DES + "\"");
System.out.println("Examples:");
System.out.println("\"keygen AES 128\" generates a key and prints it as hex-encoded");
}
}