Issue
Here is what I have from my servlet
Random random = new Random();
String salt = Integer.toString(random.nextInt(1000000000 - 1 + 1) + 1);
String sql = "insert into users (user_name, salt, password) "
+ "values (?, ?, ?)";
c = DriverManager.getConnection( url, username, password );
PreparedStatement pstmt = c.prepareStatement( sql );
pstmt.setString( 1, userName );
pstmt.setString( 2, salt);
pstmt.setString( 3, "SHA2(CONCAT('" +password1+ "', "+ salt +"), 256)");
The values for the username and password are stored correctly on the server but the password is not. It is stored as the following SHA2(CONCAT('edf', 733903552), 256) for the given values.
I am assuming the SHA2 and CONCAT function are not taking effect, been playing around with it for a while and can't figure out why.
Solution
It's a string literal being passed, and that's what's being stored. Consider:
String foo = "SHA2(CONCAT('" +password1+ "', "+ salt +"), 256)";
pstmt.setString( 3, foo );
The value of foo
is what gets passed in as a value in the SQL statement.
MySQL doesn't see any of the contents of that string as SQL text... it's just a string. (This is behavior that we want. One of the big benefits of prepared statements and bind placeholders is preventing SQL injection, that is, preventing values from being interpreted as part of the SQL.)
If you want the CONCAT
and SHA2
functions executed as MySQL functions, those need to be part of the SQL text. Pass in (as values) just password1
and salt
.
Something like this:
String sql = "insert into users (user_name, salt, password)"
+ " values (?, ?, SHA2(CONCAT( ? , ? ),256) )";
pstmt.setString( 1, userName );
pstmt.setString( 2, salt );
pstmt.setString( 3, password1 );
pstmt.setString( 4, salt );
Answered By - spencer7593