2010-09-15 7 views
1

Je suis à la recherche d'un moyen de crypter des données sur leur chemin dans une base de données MySQL, et de les décrypter à la sortie. De plus, j'aimerais pouvoir effectuer des requêtes SQL normales sur ces champs, comme la recherche et la comparaison, ce qui m'empêche d'utiliser une solution PHP pure. Cela m'amène à AES_ENCRYPT() et AES_DECRYPT(), qui peuvent être dupliqués en PHP en utilisant MCRYPT.Problème avec MySQL AES_DECRYPT

J'ai du mal avec AES_DECRYPT et j'ai essayé toutes les suggestions que je peux trouver grâce à des recherches en ligne.

Voilà ma table:

CREATE TABLE IF NOT EXISTS `test_table` (
    `id` int(6) NOT NULL, 
    `secure_info` text NOT NULL, 
    `encrypted_blob` blob NOT NULL, 
    `encrypted` text NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

J'exécute ces requêtes:

INSERT INTO test_table (id, secure_info) VALUES (1,'Testing'); 
UPDATE test_table SET encrypted = AES_ENCRYPT(secure_info,'key') WHERE id=1 LIMIT 1; 
UPDATE test_table SET encrypted_blob = AES_ENCRYPT(secure_info,'key') WHERE id=1 LIMIT 1; 

SELECT *, AES_DECRYPT(encrypted,'key') as decrypted, AES_DECRYPT(encrypted_blob,'key') as decrypted_blob FROM test_table WHERE id=1; 

Je ne peux pas obtenir la valeur d'origine. 'decrypted' renvoie NULL, et 'decrypted_blob' renvoie 54657374696e67

Des idées, ou peut-être une meilleure solution? AES_ENCRYPT renvoie une chaîne binaire. N'utilisez donc pas de type de colonne de texte.

+0

Tous le cryptage est réversible par définition. Vous confondez une fonction de résumé de message avec un chiffre. traduction md5() n'est pas le cryptage c'est une fonction de hachage. – rook

+0

Si vous souhaitez simplement stocker des valeurs cryptées, vous devez les crypter en PHP et les écrire en tant que blobs. De cette façon, la clé ne quitte jamais PHP donc la base de données n'est pas utile à un attaquant. Ce que vous semblez faire ici, c'est faire le cryptage et le décryptage dans la base de données, qui offre beaucoup moins de protection. Après tout, vous devez maintenant envoyer la clé (texte brut!) Sur le fil à chaque requête. Enfin, Rook a un point, en ce que vous devriez utiliser un résumé si vous stockez un mot de passe, pas de cryptage. –

Répondre

4

décryptage Blob fonctionne très bien, "54657374696e67" est "Test", seul hex codé. Vous exécutez probablement cela avec un outil qui affiche des blobs en hexadécimal. Le décryptage de texte ne fonctionne pas (et ne devrait pas).

+0

Merci - c'est ce que j'avais le plus de problèmes avec. Ma base de données est également configurée à UNHEX() à la sortie - je reçois le texte original quand je sélectionne! – Travis

+1

Belle prise. Vous ne voyez même pas le code hexadécimal. Tout ce que vous voyez est blonde, brune, rousse, Testing ... – webbiedave

0

Astuce: numérotera clé primaire à 1, non 0

Astuce 2: Essayez de ne pas nommer vos champs après des mots-clés MySQL. Cela peut conduire à la confusion et nécessitera généralement d'échapper avec des guillemets (text est une exception).

http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html

+0

AES_ENCRYPT ne renvoie-t-il pas simplement la valeur? J'ai deux champs, 'encrypted', et 'encrypted_blob' pour les tests, parce que je suis conscient du besoin d'un champ binaire. J'ai mis à jour mon code avec vos conseils et c'est le même résultat. Conseils très intéressants; Je serai sûr de les regarder plus loin. Merci! – Travis

+0

'AES_ENCRYPT' renvoie un binaire, ne stockez donc pas son résultat dans une colonne de texte. Votre premier 'UPDATE' le stocke dans une colonne de texte. Cela peut conduire à des erreurs de chiffrement/déchiffrement. – webbiedave

+0

Merci - Mon but avec la colonne de texte était de voir ce qui se passait. Je comprends maintenant qu'une colonne binaire est nécessaire, et la colonne de texte est entièrement inutile. – Travis

2

Les champs TEXT dans MySQL sont sujets à la conversion d'un jeu de caractères. Si vous vous connectez avec iso-8859 et que la table est stockée dans CP1252, par exemple, MySQL convertira automatiquement le texte entre les deux jeux de caractères. Cela effacera les données cryptées, car certains octets des données d'origine 8859 seront convertis en équivalents de 1252, qui ont des valeurs différentes. D'autre part, les champs BLOB sont transmis par mot de passe sans conversion, donc il n'y a pas d'erreur de déchiffrement.

+0

Merci - c'est très utile! – Travis

0

Si vous utilisez AES_ENCRYPT pour chiffrer une chaîne de caractères, alors AES_DECRYPT ne renvoie pas une chaîne de caractères mais un tableau de System.Byte. J'utilise le code suivant pour restaurer une chaîne:

  Dim back As System.Byte() 
      back = DirectCast(reader(x), System.Byte()) 
      Dim s As String = "" 
      For Each b As Byte In back 
       s &= Chr(b) 
      Next 
0

d'accord avec @ user187291

Je faisais la même question et découvert une option cochée dans mon phpmyadmin

Afficher le contenu binaire comme HEX

quand je lance la même requête dans MySQL commandline il me affiche le résultat correct