The person who told me the key and the way it's decrypted also gave me this
# base64 data must be stored in a file named "...-tmp.decrypt"
# Usage: decrypt.sh secret sessionId
SALT="$(cat $2 | base64 -d | head -c +8 | od -A n -t x1 | head -n 1 | tr -d " ")"
echo -n "Salted__" > $2.enc cat $2 | base64 -d >> $2.enc cat $2.enc | openssl aes-256-cbc -d -k "$1" -md md5 -S "$SALT"
what we have here
- the salt is made of first 8 bytes of the input
- the aes-256-cbc is used
Constants:
private static final int SALT_LENGTH = 8;
private static final int ITERATIONS = 1;
private static final int KEY_SIZE_BITS = 256;
private static final int INDEX_KEY = 0;
private static final int INDEX_IV = 1;
divide salt and input
// iv is 8 bytes of the input
byte[] inputBytes = Base64.getDecoder().decode(INPUT);
byte[] salt = new byte[SALT_LENGTH];
System.arraycopy(inputBytes, 0, salt, 0, SALT_LENGTH);
byte[] encrypted = new byte[inputBytes.length - SALT_LENGTH];
System.arraycopy(inputBytes, SALT_LENGTH, encrypted, 0, encrypted.length);
and decrypt (where did you get the original code from? attribution to the original author wouldn't hurt)
Cipher aesCBC = Cipher.getInstance("AES/CBC/Pkcs5Padding");
MessageDigest md5 = MessageDigest.getInstance("MD5");
// --- create key and IV ---
// the IV is useless, OpenSSL might as well have use zero's
final byte[][] keyAndIV = EVP_BytesToKey(
KEY_SIZE_BITS / 8,
aesCBC.getBlockSize(),
md5,
salt,
PASSWORD_STRING.getBytes("UTF-8"),
ITERATIONS);
SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES");
IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]);
// --- initialize cipher instance and decrypt ---
aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decrypted = aesCBC.doFinal(encrypted);
System.out.println(new String(decrypted, "UTF-8"));
and we get a result
{"difficulty":5,"friend_id":1962395051,"is_playing_script":true,
"selected_team_num":3,"support_items":
[{"quantity":2,"support_item_id":6},{"quantity":2,"support_item_id":1505},{"quantity":2,"support_item_id":1202},{"quantity":2,"support_item_id":1701}]}
Still I see 2 things missing:
- password strength
as @dave_thompson_085 pointed out, the password looks like part of a PEM file and I agree with him. That's very wrong as the PEM file has defined rigid schema and that will effectively lower randomness of the password
I advice to use really random password, e,g, generated as
openssl rand -hex 16
openssl rand -base64 16
- authenticated encryption
the ciphertext doesn't contain any integrity information so in case the ciphertext is be altered, there is no option the alteration is detected, so you cannot ensure integrity
extra integrity information needs to be sent along the ciphertext (e.g. hmac of the ciphertext)