Block ciphers, salt, AES, MySQL, and best practices around credential storage

∥☆過路亽.° 提交于 2019-12-01 21:45:51

Usually for standard AES you'd supply a nonce (the IV), in order to avoid the problem you describe.

A way to drastically improve the quality of the encrypted data is to use a different master password for every account instead of varying the IV. Basically this is some data which you mix with the password. You can do this many ways, the simplest is to do a concat.

E.g.

  1. Create a random sequence.
  2. Store nonce || HEX(AES_ENCRYPT(password_to_store, master_password || nonce)
  3. Retrieve by extracting the nonce, then decrypt the data with master_password || nonce.

Here is an example, with the unique nonce 'iej383u8fjeiw' (Each time you encrypt you need to generate a new one)

SELECT CONCAT('iej383u8fjeiw', ':', HEX(AES_ENCRYPT("password", CONCAT("master_password", "iej383u8fjeiw")))) 
-> "iej383u8fjeiw:61224653D4DA33D57A42FE5E5E10DEA9"

SELECT AES_DECRYPT(UNHEX(SUBSTRING_INDEX('iej383u8fjeiw:61224653D4DA33D57A42FE5E5E10DEA9', ':', -1)), CONCAT('master_password', SUBSTRING_INDEX('iej383u8fjeiw:61224653D4DA33D57A42FE5E5E10DEA9', ':', 1))) 
-> "password"

Or with variables:

SELECT CONCAT(nonce, ':', HEX(AES_ENCRYPT(password_to_encrypt, CONCAT(master_password, nonce)))) 
-> encrypted password

SELECT AES_DECRYPT(UNHEX(SUBSTRING_INDEX(encrypted_password, ':', -1)), CONCAT(master_password, SUBSTRING_INDEX(encrypted_password, ':', 1)))
-> password_to_encrypt

That said, although significantly more secure than the version without a nonce, there are plenty of weaknesses and attacking vectors left. For example, logging of queries or sniffing mysql packets will reveal both password and master password!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!