2013-04-30 82 views
0

我有一个用户名和加密的密码表。MySQL加密()与盐接受密码后的随机字符

密码通过MySQL加密()与盐(密码的前两个字符)一起进行加密。

最近我已经注意到MySQL即使在最后包含随机字符也会接受密码。

假设我们有这样的表:

SET NAMES utf8; 
SET foreign_key_checks = 0; 
SET time_zone = 'SYSTEM'; 
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; 

DROP TABLE IF EXISTS `user`; 
CREATE TABLE `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `username` varchar(255) DEFAULT NULL, 
    `password` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

INSERT INTO `user` (`id`, `username`, `password`) VALUES 
(11, 'ricardomontalban', ENCRYPT(11111111,11)); 

现在我查询我的用户:

-- The following shows the appropriate response -- 
SELECT * FROM user WHERE username = "ricardomontalban" AND password = ENCRYPT(11111111,11); 

-- HOWEVER, the following query also shows a result, even with random characters appended!!! -- 
SELECT * FROM user WHERE username = "ricardomontalban" AND password = ENCRYPT("11111111-55669964s5465sqsfqsdf",11); 

-- No problem with prepended random characters though -- 
SELECT * FROM user WHERE username = "ricardomontalban" AND password = ENCRYPT("smlkfjmlsdkfjslqf-11111111",11); 

我创建了一个SQL小提琴实时显示这个例子: http://sqlfiddle.com/#!2/898d5/9

我在做什么错?我是否应该使用这种加密方法? 任何建议,非常感谢。

回答

4

作为每documentation

ENCRYPT()忽略所有但str的前八个字符,至少在一些系统。这个行为由crypt()系统调用的实现决定。

+0

感谢您的回答。这是否意味着密码只能允许长度为8个字符?你会建议不使用这种加密方法吗? – maartenmachiels 2013-04-30 15:44:58

+0

不要使用加密密码。这几天它是一个无用的散列。如果你需要安全性,那么使用强大的散列(md5,sha1)作为启动点,并认真考虑专用于pw保护的散列,如bcrypt。 md5/sha1总比没有好,但是它们对计算要求非常敏感,它们变得非常容易暴躁。 – 2013-04-30 15:45:56

+0

谢谢。那就是加密。你知道任何有关bcrypt入门的好参考吗? – maartenmachiels 2013-04-30 15:48:14

1

为了回答您的其他问题:

从密码使用前两种(或任何)字符作为盐也是错误的。 salt的想法是为加密密码提供一些随机性,以便拥有相同密码的用户拥有不同的哈希值。

对于您正在使用的任何编程语言,使用已建立的加密库(如bcrypt)。

+0

感谢您指出了这一点! – maartenmachiels 2013-04-30 15:50:40