-1

The following encryption and decryption works fine in mysql (aes-256-cbc) mode

SET block_encryption_mode = 'aes-256-cbc';

select
cast(
aes_decrypt(
from_base64('StThdNXA+CWvlg+of/heJQ=='),
sha2(concat('ssshhhhhhhhhhh!!','ENCRYPTION_KEY$&'),256),
'ssshhhhhhhhhhh!!'
)
as char);

select to_base64(aes_encrypt(
'test_value',
sha2(concat('ssshhhhhhhhhhh!!','ENCRYPTION_KEY$&'),256),
'ssshhhhhhhhhhh!!'
));

I am trying to decrypt value that was encrypted in mysql but no luck.

The following is the key in my mysql query sha256(salt+key)

select sha2(concat('ssshhhhhhhhhhh!!','ENCRYPTION_KEY$&'),256);

The same value I am able to get in java :

Hashing.sha256().hashString("ssshhhhhhhhhhh!!ENCRYPTION_KEY$&", StandardCharsets.UTF_8).toString();

Is there a custom way I can make bouncy castle/other API use same secret key to decrypt ?

Topaco
  • 40,594
  • 4
  • 35
  • 62
Barath
  • 1
  • 4

1 Answers1

-1

MySQL internally uses OpenSSL algorithm with EVP_BytesToKey as the derivation function. Check out this url

MySQL encrypt and decrypt sample:

SET block_encryption_mode = 'aes-128-cbc';
SET block_encryption_mode = 'aes-256-cbc';
select 
cast(
    aes_decrypt(
        from_base64('MKicK+vAcZkq/g3wpTKxVg=='),
        'ENCRYPTION_KEY$&',
        'ssshhhhhhhhhhh!!'
    )
as char);


select to_base64(aes_encrypt(
'test_value',
'ENCRYPTION_KEY$&',
'ssshhhhhhhhhhh!!'
));

There is a JAR that supports this EVP_BytesToKey key derivation function.

 JAR : not-going-to-be-commons-ssl-0.3.19

public class AnotherTry {

byte[] key = "ENCRYPTION_KEY$&".getBytes(StandardCharsets.UTF_8);
byte[] iv = "ssshhhhhhhhhhh!!".getBytes(StandardCharsets.UTF_8);

String cipher = "AES-128-CBC";

@Test
public void testEncrypt() throws Exception {
    byte[] data = "test_message".getBytes(StandardCharsets.UTF_8);
    byte[] encrypted = OpenSSL.encrypt(cipher, key, iv, data, true);
    System.out.println(new String(encrypted));
}

@Test
public void testDecrypt() throws GeneralSecurityException, IOException {
    byte[] encrypted = "rQ8Y0ClNu5d4ODZQ3XcQtw==".getBytes(StandardCharsets.UTF_8);
    byte[] decrypted = OpenSSL.decrypt(cipher, key, iv, encrypted);
    System.out.println(new String(decrypted));
}

}

This way interoperability is achieved, finally ! Hope this helps someone who's trying to do the same.

Barath
  • 1
  • 4
  • Sorry, but this answer is not correct: `EVP_BytesToKey()` is *not* the KDF of MySQL. The posted codes are also *not evidence* for or against a particular KDF, as both codes simply do not use a KDF at all. – Topaco Jun 10 '22 at 13:43
  • The former can be easily proven by comparing both KDFs (s. [`Evp_BytesToKey()`](https://stackoverflow.com/a/11786924) vs [MySQL's KDF](https://github.com/mysql/mysql-server/blob/8d8c986e5716e38cb776b627a8eee9e92241b4ce/mysys/my_aes.cc#L55)). The latter is because in the posted codes a *valid* AES key size is used. Therefore MySQL applies the key *directly*, so without KDF (see Approach 1 of my answer). And the Java code uses an [overload](https://github.com/narupley/not-going-to-be-commons-ssl/blob/master/src/main/java/org/apache/commons/ssl/OpenSSL.java#L402) where no KDF is involved either. – Topaco Jun 10 '22 at 13:47
  • The question is more related to interoperability between java and mysql :) – Barath Jun 14 '22 at 06:58
  • I don't understand your comment, of course it's about interoperability between Java and MySQL. But your answer does not explain the *actual* problem from your question: In the MySQL code of your question, a KDF is applied, but not in the Java code, which is why decryption with Java fails. In your answer, however, neither the MySQL code nor the Java code applies a KDF, which is why decryption with Java works. Yet you give the impression that a KDF is applied and that it is `EVP_BytesToKey()`, both of which are easily provably false (see links above). – Topaco Jun 14 '22 at 07:50