admin管理员组

文章数量:1334282

With Java I generate and encrypted String like:

TextEncryptor textEncryptor = .springframework.security.crypto.encrypt.Encryptors.text(secretKey, salt);
String cryptedString = textEncryptor.encrypt('Original String');

The cryptedString is 64 bytes long (like '2883d27d38b7ff4faf6c115e7d80854fabbe32decd24292f403e5a314a3d00a6'). It has been generated with an AesBytesEncryptor which generated a 32 bytes length String (by example '(��}8��O�l^}��O��2��$)/@>Z1J= �'), encoded to Hexadecimal String cryptedString.

The problem is that I want to generate such a String directly into Mariadb database, with function AES_ENCRYPT. But when I use by example

SELECT HEX(AES_ENCRYPT('Original String', 'secretkey', 'abcd1234cdef5678', 'aes-256-cbc'));

the return value is 16 bytes length (by example '63235D6C3CC93ED23E889BAE10236CC1'), meaning that AES_ENCRYPT returned a String of 16 bytes length and not 32 bytes!

How can I make AES_ENCRYPT function return a 32 bytes length String?

I tried:

SELECT AES_ENCRYPT('Original String', 'secretKey', 'abcd1234cdef5678', 'aes-256-cbc');

that returned (example): %äµ ®bY[Ù$[¾#

which is of 16 bytes length, but I would like it to return a 32 bytes length String, like in my Java code

With Java I generate and encrypted String like:

TextEncryptor textEncryptor = .springframework.security.crypto.encrypt.Encryptors.text(secretKey, salt);
String cryptedString = textEncryptor.encrypt('Original String');

The cryptedString is 64 bytes long (like '2883d27d38b7ff4faf6c115e7d80854fabbe32decd24292f403e5a314a3d00a6'). It has been generated with an AesBytesEncryptor which generated a 32 bytes length String (by example '(��}8��O�l^}��O��2��$)/@>Z1J= �'), encoded to Hexadecimal String cryptedString.

The problem is that I want to generate such a String directly into Mariadb database, with function AES_ENCRYPT. But when I use by example

SELECT HEX(AES_ENCRYPT('Original String', 'secretkey', 'abcd1234cdef5678', 'aes-256-cbc'));

the return value is 16 bytes length (by example '63235D6C3CC93ED23E889BAE10236CC1'), meaning that AES_ENCRYPT returned a String of 16 bytes length and not 32 bytes!

How can I make AES_ENCRYPT function return a 32 bytes length String?

I tried:

SELECT AES_ENCRYPT('Original String', 'secretKey', 'abcd1234cdef5678', 'aes-256-cbc');

that returned (example): %äµ ®bY[Ù$[¾#

which is of 16 bytes length, but I would like it to return a 32 bytes length String, like in my Java code

Share Improve this question edited Nov 20, 2024 at 17:53 Jason Aller 3,65228 gold badges41 silver badges39 bronze badges asked Nov 20, 2024 at 8:37 GigiGigi 11 bronze badge 5
  • Adjust block_encryption_mode value as you need. – Akina Commented Nov 20, 2024 at 9:11
  • 1 Have a look at the documentation of TextEncryptor#text() and AES_ENCRYPT(). The former additionally performs a key derivation via PBKDF2 (see standard link), the latter does not. – Topaco Commented Nov 20, 2024 at 9:14
  • 1 With KDF(), however, a key derivation can be carried out via PBKDF2, so that (theoretically) the same functionality should be implementable as with TextEncryptor#text(). The reason for the different lengths may be that TextEncryptor#text() generates a random IV that is (presumably) prepended to the ciphertext, while AES_ENCRYPT() only returns the ciphertext. – Topaco Commented Nov 20, 2024 at 9:15
  • @NullUserException - The IV is required for decryption. It is not secret and is passed together with the ciphertext. How you do this is up to you. Concatenating the IV and ciphertext is a convenient way and is therefore usually used. On the decrypting side, IV and ciphertext are separated and decryption is performed. – Topaco Commented Nov 21, 2024 at 19:02
  • @Topaco Ah, yes. I misremembered how CBC works -- I was assuming the IV is prepended to the plaintext (which essentially would have meant the first block to be encrypted is the IV itself). But the IV is just XOR'd with the first block. You're right. – NullUserException Commented Nov 21, 2024 at 22:04
Add a comment  | 

2 Answers 2

Reset to default 0

Finally I didn't user mariadb function, but I created a single jar file with a main function that called the textEncryptor.encrypt() method on the input string passed to main.

So, when calling "java -jar myFile.jar myKey mySalt myInputString" I'm sure that the result string is exactly encrypted as I want to.

Ciao everybody !

256 bit encryption take a 256 bit input, using 256 bit key, and outputs 256 bits, and when there are multiple chunks, the chaining (CBC) determines how output is mixed with the next input to produce the next chunk of output.

Divide 256 bits by 8 bits per byte is 16 bytes.

Your input string of 15 bytes so got padded to 16 bytes, in the input, and the output is of the same size. Hex encoding of 16 bytes doubles the length as it takes two bytes or output (00 -FF) to represent one byte of input.

On the assumption that both SQL and Java of the plaintext string are in a latin1 (1 byte per char) input.

To get 32 bytes of output you need to provide 17-32 bytes of input for the AES 256 algorithm.

Java concatenates a 16 byte IV to the initial string, however MariaDB and its underlying OpenSSL/WolfSSl/Schannel processes the IV by an XOR to the initial plain text per the Cipher Block Chaining defined mechanism, being the length is the same as the initial plaintext (rounded up to 16 bytes).

本文标签: javaHow to generate a 32 bytes result string with mariadb function AESENCRYPTStack Overflow