How to store AES encrypted information in MySQL database - mysql

I have a piece of information which is encoded using aes-256-cbc encryption. How should I store it in the database? Currently I'm using VARCHAR(255) utf8_bin. Is this OK or should I use other field type like VARBINARY(255)? Is there a possibility of losing some data using VARCHAR in this case? Thanks.

The possible (in)appropriateness of storing encrypted (as opposed to hashed) passwords in a database notwithstanding, AES ciphertext is binary data, and therefore should be stored as such, i.e. in a BINARY / VARBINARY column or a BLOB.
It's also possible to encode the ciphertext e.g. as base64, and then store it in a text (i.e. CHAR / VARCHAR / TEXT) column. This is less space-efficient, but it may sometimes be more convenient, e.g. when inspecting the data visually or passing it between programs that may have trouble dealing with fields containing arbitrary binary data.

Related

Data type blob mysql

My colleague setup a MySql database. For two fields where one can enter longer text he used database type BLOB. The problem now is when someone is entering German "Umlaute(ä,ö,ü)". These are not shown properly when I retrieve it later from the database to show it to the user. Instead they are shown as weird signs. I mean, in my java code these Blob objects are simple Strings. What can I do to show these special character (Umlaute) properly again?
Short answer: you need to change the column type to TEXT.
The first B in BLOB stands for binary. With such column type you're telling MySQL explicitly that you don't want its contents to be handled as text. For that reason, you'd need to ask everyone who enters data what encoding they are using and then make a conversion from that encoding to your application's encoding. Of course, you also don't have any way to control how others are writing and reading data so you could eventually find different encodings in different rows.
BTW, both BLOB and TEXT have a maximum length of 65,535 (216 − 1) (bytes in the case of BLOB, characters in the case of TEXT), the same as VARCHAR. If you really want large text that don't fit in VARCHAR you may want to consider larger types like MEDIUMTEXT or LONGTEXT.

store 300 digit number in sql

Which datatype can I use to store really big integer in SQL. I am using phpmyAdmin to view data and java program for storing and retrieving values. Actually I am working with Bilinear Maps which uses random numbers generated from Zp where p is very large prime number and then "raised to" operations on those number.
I want to store some numbers in database like public keys. What data type can I use for table columns in SQL for such values?
You could store them as strings of decimal digits using type CHARACTER. While this does waste some space, an advantage is that the database will be easier for humans to understand.
You could store them as raw binary big-endian values using type BLOB. This is the most efficient for software to access and takes up the least space. However, humans will not be able to easily query the database for these values or understand them in dumps.
Personally, I would opt for the blob unless there's a real need for the database to be understandable by humans using standard query tools. If you can't get around needing to administer the database with tools that don't understand your data format, then just use decimal values in text.
For MySQL, VARCHAR(300) CHARACTER SET ascii.
VAR, assuming the numbers won't always be exactly 300.
CHAR -- no big advantage in BLOB.
ascii -- no need for utf8 involvement.
DECIMAL won't work because there is a 64-digit limit.
The space taken will be 2+length bytes (302 in your example), where the 2 is for length for VAR.

How do I use varbinary if I don't know the length of my text

I want to encrypt text using AES in mysql, but I have a small problem, because you need to use varbinary to store these.
Some of my datatypes are varchar and yes I can probably work out the length of my varbinary for these. However for my address fields I use the TEXT datatype, as we have Chinese addresses stored and these can be very long. I use the TEXT datatype because you do not need to specify a length in mysql.
The problem is that with varbinary you need to specify a length, and I don't really know the length because the addresses can be of any length.
Is there some kind of binary datatype I can use for AES where I don't have to specify the length of the data?
As per comments - you require BLOB data type, which is short for Binary Large Object (thanks Maarten Bodewes for clarification).
A BLOB data type won't store character set with the information and is equivalent to TEXT type, without a charset. As mentioned in the comments, there are other types such as MEDIUMBLOB, TINYBLOB, LARGEBLOB, they are all covered on MySQL's manual page.

What is the best MYSQL or Maria DB data type to store JWT token?

I'm using the following technology stack
Laravel 5.2
MySQL
and for security I'm using JWT (JSON Web Tokens)
I was able to secure my applications using JWT.
I would like to store JWT token in mysql database.
QUESTION Which of the following data type is best to store JWT token in MySQL DB?
VARCHAR
CLOB
TEXT
LONG TEXT
As with anything else, the answer is "it depends".
First, you need to determine if storing the fully encoded JWT is the correct solution. I tend to not store the JWT string and instead store the claims used to construct the JWT, which will save a ton of room in the database.
If you decide that storing the JWT is the correct method, then we can look at your options.
TEXT and LONGTEXT are just types of CLOB, so we can ignore that one.
TEXT and VARCHAR both have limits of 64kb, so anything above that will require LONGTEXT (or MEDIUMTEXT, which you didn't mention but is an option).
The difference between TEXT and VARCHAR is that VARCHAR is stored in the row but TEXT is basically a pointer. VARCHAR will be faster if you are going to be reading the JWT often, but larger strings will cause each individual row to be larger, which will be a performance hit.
With as large as JWTs tend to be, I would say that TEXT is a pretty good choice to store JWTs in the database. If you are absolutely confident that the JWTs will stay very small, then a VARCHAR may produce better read performance, but you would would be best to test with real world data to be sure.
If you need a field larger than TEXT is able to provide, then I would reiterate my recommendation to avoid storing the encoded JWT, but LONGTEXT is an option there.
Based on the example, I would suggest this for an 'encoded' base64 token:
TEXT CHARACTER SET ascii COLLATE ascii_bin
In general, JSON should be some size of TEXT or VARCHAR with CHARACTER SET utf8 or utf8mb4. (The COLLATION is likely to be irrelevant.)
TEXT is limited to 64KB; there is not much advantage in using a smaller VARCHAR.
Re: "TEXT is just a pointer" -- Not quite correct. In some ROW_FORMATs in InnoDB, either TEXT or VARCHAR may be a pointer to an extension to the row. The action depends mostly on the ROW_FORMAT, not the datatype.

BINARY type MYSQL field with bcrypt

I was taking a look at this question regarding the field length and type to use for bcrypt hashes. Several the answers mention using the BINARY MYSQL column type. However, when reading from this column with the mysql node.js module, it reads BINARY columns into a buffer type rather than a string. The bcrypt compare function bcrypt.compare(password, hash, callback) does not like the buffer type:
Error: data and hash must be strings
at node_modules/bcrypt/bcrypt.js:150:16
This leads me to two questions:
First, I assume that what I want to do is hash_buffer.toString(), but I notice in the documentation that there are different character encodings that can be used. I'm not sure what the correct encoding to use is since the data doesn't really represent actual characters. Since I want the binary data to remain unchanged, I would guess ASCII. Can anyone confirm this?
Second, I don't understand why not to use the CHAR data type. The hash is specifically made to be a printable string. I understand that the MYSQL comparisons might not be made as expected, but there is no appropriate time to search for or sort by a password hash anyways.
Generally speaking, it makes sense to use BINARY columns to store bcrypt hashes if MySQL is the one doing the comparison. A binary collation will prevent unwanted comparison results, e.g. 'A' being equal to 'a'; this makes a big difference in Base64 encoding.
However, if the comparison is exclusively performed in the application, you can save yourself the trouble and use a regular CHAR column for storing the hash.