简体   繁体   中英

Trying to Store SecretKey, Encrypted Password in MySQL through JDBC

I'm trying to create my own little program for fun that allows the user to create a username/password which will then be encrypted using AES, and then store the username, encrypted password, and the key in a MySQL database. My future plan is to allow the user to "log in" by retrieving this information from the database and decrypting it to check the login information against the database.

Currently, I've got all of the encryption/decryption functionality working in Java. I've tested it using a variety of inputs and I know the methods all work correctly. The issue I'm running into involves storing this information in a MySQL database. I'm able to connect to the database and execute SELECT queries just fine, but when I go to store the information using an INSERT statement, I'm getting errors.

Here is the setup of my MySQL database:

mysql> SHOW COLUMNS FROM Accounts;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| username | varchar(45) | NO   | UNI | NULL    |                |
| password | blob        | NO   |     | NULL    |                |
| key      | blob        | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

Here is the code in question:

public static void main(String[] args) throws Exception {

    String plainText = "test"; 
    SecretKey secKey = getSecretEncryptionKey(); // working correctly
    byte[] cipherText = encryptText(plainText, secKey); // working correctly
    String decryptedText = decryptText(cipherText, secKey); // working correctly
    byte[] secKey2 = secKey.getEncoded(); // necessary??

    try{  
        Class.forName("com.mysql.jdbc.Driver"); 
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/Test?useSSL=false","****","****");  // user/pass commented out
        Statement stmt = con.createStatement();  
        ResultSet rs = stmt.executeQuery("use Test;");  
        stmt = con.createStatement(); 
        stmt.executeUpdate("INSERT INTO Accounts (username, password, key) VALUES ('test1', '"+cipherText+"', '"+secKey2+"');");
        con.close();
    } catch(Exception e){ 
        System.out.println(e);
    }  

}

The error I get:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key) VALUES ('test1', '[B@735b478', '[B@2c9f9fb0')' at line 1

The schema I use in my database is called "Test." The "use Test" Query does seem to work.

In the example above, "test1" would be the username, cipherText would be the hashed password, and secKey2 would be the key encoded into a byte array.

I've tried doing this both with and without converting the Key to a byte array, since I read it's best to convert the key to a byte array and store as a blob. I've also tried this with the 'password' and 'key' fields as VARCHARs. I've not included the methods for the encrypting/decrypting since I know they work correctly, the issue is storing the information in the database.

Any help would be greatly appreciated!

At the root, you're trying to store two byte arrays into appropriate columns. The problem you're seeing is caused by the string concatenation you're using to create the insert statement. When you say "INSERT INTO Accounts (username, password, key) VALUES ('test1', '"+cipherText+"', '"+secKey2+"');" what you're really saying is "INSERT INTO Accounts (username, password, key) VALUES ('test1', '"+cipherText.toString()+"', '"+secKey2.toString()+"');" Those [B@735b478 and [B@2c9f9fb0 values are (effectively) pointer addresses for those arrays because that's the default Object.toString() implementation.

You should not create SQL statements by string concatenation. On top of opening you to SQL Injection you end up with code that is hard to read and maintain. Use PreparedStatement instead of Statement and that will let you use the setBlob() methods. Not sure how to get a Blob out of a byte[] though. You could also Base64 encode the byte[] 's and store them as varchars, but that's a whole other topic.

As for whether you should store a password in any kind of reversible form in your DB, see here .

The answer of @Jose_Ferrer is totally right in pointing some of the issues of the code (eg: that you are storing the addresses of the byte array and not the calculated hash).

However, the syntax error message you are encountering is not directly related to this: you would end up with useless strings stored in the database, but that's not something the database can complain about.

The syntax error seems due to the usage of the "key" reserved word as a field of the table. The SQL parser is complaining of finding a keyword (key) where it expects a field name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM