How can I encrypt a value in MySQL? - mysql

I have this code:
CREATE TABLE Person
(
primaryKey int unsigned NOT NULL,
emailAddress mediumblob NOT NULL
);
What attribute (like NOT NULL) can I use so that the emailAddress would be encrypted?
I would greatly appreciate the help. I tried encrypt() but that's giving me errors.

if you looking to encrypt data where you can decrypt it later then you should use ES_ENCRYPT() AND AES_DECRYPT()
According to the Manual
AES_ENCRYPT() encrypts a string and returns a binary string. AES_DECRYPT() decrypts the encrypted string and returns the original string. .
MySQL 5.1 Doc: AES_ENCRYPT() / AES_DECRYPT()
you can use it like this
INSERT INTO table (email)VALUES(AES_ENCRYPT('myemail', 'secrectkey' ))
to read the data that is encrypted you can do this
SELECT AES_DECRYPT(email, 'secrectkey' ) FROM table
where secrectkey is really a secret value that only authorized users should have access to
But if you are looking for hashing "a one way hash that can't be read back in plain text" you can use one of the following functions
MD5('myemail');
OR
PASSWORD('myemail');
OR
SHA1('myemail');
Then your table length depends on the encryption method you use. you can use VARCHAR() if the length of your encrypted message changes. If you know that you will be using fixed length I would use CHAR(exact_length)
Again the length will depend on the method you use.

You have the complete list of encryption functions supported by MySQL DBMS on this official documentation.

Related

bigint not insert correctly

I have a database and a bigint column type. Everytime I insert value to this column I always got the wrong number. for example, I insert value "198705122006041001" and it always insert this value "2147483647".
I use laravel for my project, if I use eloquent to display the bigint it wont display correctly but if I use PDO manually, it will display correctly.
PHP has no bigint data type, it overwflows and uses int.max instead. You have to represent bigints as string or float. Be aware, that float is not precise and can lead to surprises.
Do the mathematical transformations in MySQL and don't forget to cast to bigint when necessary.
You should check this again, because it's definitely int, but not bigint. 2147483647 is a maximum possible value for signed int
See https://laracasts.com/discuss/channels/eloquent/fbid-bigint-with-model-and-eloquent. A Laravel user had the same problem, and eventually had to cast the result to a string.
Another user comment pointed out that XAMPP provides only a 32-bit PHP binary, which limits the size of a PHP integer.
Check your PHP integer size with this code:
<?php
echo "Integer size can be determined using the constant PHP_INT_SIZE="
. (PHP_INT_SIZE * 8)
. " bits, maximum value using the constant PHP_INT_MAX="
. PHP_INT_MAX;
See also http://php.net/manual/en/language.types.integer.php
Install https://laravel.com/docs/5.3/homestead and get a 64-bit PHP binary.

AES_DECRYPT How do you check value is already decrypted in mysql

I want to decrypt fields in my database using sql on mysql but before I decrypt I need to check if the fields can be decrypted.
update customer
set name = aes_decrypt(from_base64(name), 'key')
If the provided key is wrong or data is invalid the name field will be set to null;
I have tried adding a where clause like below to make sure the field name is not already decrypted but this doesn't work all the time as the aes_decrypt can return null or garbage if the key is incorrect or data is invalid.
update customer
set name = aes_decrypt(from_base64(name), 'key')
where aes_decrypt(from_base64(name), 'key') is not null.
So how can I check if the returned value is null or "garbage"? Or what other approach is there?
From mysql doc: "it is possible for AES_DECRYPT() to return a non-NULL value (possibly garbage) if the input data or the key is invalid."
garbage example I get: w���� ��Y�'v��Y�m��_
Thanks
Instead of storing raw ciphertext, follow the lead of version 2 of Defuse Security's PHP encryption library:
Use authenticated encryption.
Use a version tag which tells what library was used as well as what version and any optional configuration information you need to add.
Make sure to calculate HMAC(tag || IV || ciphertext) instead of just HMAC(ciphertext).
Store the tag, IV/nonce, ciphertext, and MAC together; preferably as a hex- or base64-encoded string.
Then the question becomes "Do the first N bytes of the string evaluate to a known version tag of my encryption library"?

Mysql Date Encryption

I am using AES_ENCRYPT method to encrypt the Mysql data's but when i tried it for Mysql Date type field which is not working. How to encrypt Mysql Date field using the AES_ENCRYPT? I have tried it by googleing it but no luck so far.
From the mysql manual:
AES_ENCRYPT() encrypts a string and returns a binary string.
AES_DECRYPT() decrypts the encrypted string and returns the original string.
The input arguments may be any length.
If either argument is NULL, the result of this function is also NULL.
This means you need to store encrypted data in a column of varchar or text type.

how to query a blob data

I have a table like :
------------------------------
Test_Id Test_data
(String) (blob)
------------------------------
I want a query to retrieve all the Test_Id's for a matching Test_data.
To achieve something like : select * from test_table where Test_data = blobObject;
How can we do above ??
First: there's no such thing as a string in MySQL. Only char/varchar/text.
Well you could cast it as char for comparison like this:
select * from test_table where Test_data = CAST( blobObject AS CHAR );
what's probably better is to convert your string to a binary string, but this might not give you the right comparison if you expect string comparison behaviour... well best you have a look at the char functions here:
http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html
You can use a hash function such as MD5
SELECT * FROM example_table WHERE MD5(blob_column) = 'a6a7c0ce5a93f77cf3be0980da5f7da3';
MySQL has data types which can store binary data. Not only char/varchar/text, but also BINARY/VARBINARY/BLOB.
See http://dev.mysql.com/doc/refman/5.5/en/blob.html
And it's usage is as simple as normal string type. But, escaping is required. and query length is must specified because binary data may contain NULL character in their contents.
Before MySQL 3.23 (I guess), There were only mysql_query(), mysql_escape_string(). Those function has no capability specifying query length. after BLOB has been introduced in MySQL, mysql_real_query() and mysql_real_escape_string() supported.
I found some examples for you. May this links help you!
http://zetcode.com/db/mysqlc/
http://bytes.com/topic/c/answers/558973-c-client-load-binary-data-mysql

Storing MySQL GUID/UUIDs

This is the best way I could come up with to convert a MySQL GUID/UUID generated by UUID() to a binary(16):
UNHEX(REPLACE(UUID(),'-',''))
And then storing it in a BINARY(16)
Are there any implications of doing it this way that I should know of?
Not many implications. It will slow down the queries a little, but you will hardly notice it.
UNIQUEIDENTIFIER is stored as 16-byte binary internally anyway.
If you are going to load the binary into a client and parse it there, note the bit order, it may have other string representation than the initial NEWID().
Oracle's SYS_GUID() function is prone to this issue, converting it to a string gives different results on client and on server.
From MySQL 8.0 and above you could use UUID_TO_BIN:
UUID_TO_BIN(string_uuid), UUID_TO_BIN(string_uuid, swap_flag)
Converts a string UUID to a binary UUID and returns the result. (The IS_UUID() function description lists the permitted string UUID formats.) The return binary UUID is a VARBINARY(16) value.
CREATE TABLE t (id binary(16) PRIMARY KEY);
INSERT INTO t VALUES(UUID_TO_BIN(UUID(), true));
INSERT INTO t VALUES(UUID_TO_BIN(UUID(), true));
INSERT INTO t VALUES(UUID_TO_BIN(UUID(), true));
SELECT *, BIN_TO_UUID(id) FROM t;
DB-Fiddle.com Demo