OLD_PASSWORD 5.7.5+ 中的函数
OLD_PASSWORD Function in 5.7.5+
我在这里使用的是遗留代码库,该代码库目前使用 OLD_PASSWORD()
作为简单的哈希函数。此代码库现在需要连接到数据库 运行 MySQL 5.7.
的最新版本
PASSWORD()
的等价物似乎是:UPPER(SHA1(UNHEX(SHA1(password))))
。
是否有与OLD_PASSWORD()
类似的等价物?
似乎没有等效于使用 MySQL 函数的 OLD_PASSWORD()
,除非服务器允许设置全局变量。通过执行查询 SET @@global.old_passwords = 1;
,作为具有超级权限的用户,PASSWORD()
函数然后使用 OLD_PASSWORD()
算法散列密码。
如果像我们上面的例子一样,您没有超级用户(Google CloudSQL 不支持它们),则需要替换算法。以下是不同语言的替换:
免责声明:MySQL的旧密码在现代安全中起作用are a joke,应该不尽可能使用;这些算法一团糟。
我试图直接在 SQL 中为 OLD_PASSWORD 编写一个替换用户定义的函数,它似乎可以正常工作。该代码是在 post.
中找到的 PHP 版本的翻译
DROP FUNCTION IF EXISTS OLD_PASSWORD;
DELIMITER $$
CREATE FUNCTION OLD_PASSWORD (input BLOB)
RETURNS CHAR(16)
DETERMINISTIC
BEGIN
DECLARE nr BIGINT;
DECLARE nr2 BIGINT;
DECLARE ad BIGINT;
DECLARE inlen INT;
DECLARE i INT;
DECLARE b CHAR;
DECLARE tmp INT;
DECLARE output CHAR(16);
SET nr = 1345345333;
SET nr2 = 0x12345671;
SET ad = 7;
SET inlen = LENGTH(input);
SET i = 1;
IF (input = '' OR input IS NULL) THEN
RETURN input;
END IF;
WHILE i <= inlen DO
SET b = MID(input, i, 1);
IF b != ' ' AND b != '\t' THEN
SET tmp = ORD(b);
SET nr = nr ^ ((((nr & 63) + ad) * tmp) + ((nr << 8) & 0xFFFFFFFF));
SET nr2 = nr2 + (((nr2 << 8) & 0xFFFFFFFF) ^ nr);
SET ad = ad + tmp;
END IF;
SET i = i + 1;
END WHILE;
SET nr = nr & ((1 << 31) - 1);
SET nr2 = nr2 & ((1 << 31) - 1);
SET output = LOWER(CONCAT(LPAD(HEX(nr),8,'0'), LPAD(HEX(nr2),8,'0')));
RETURN output;
END$$
DELIMITER ;
希望这对您有所帮助。但注意:以这种格式保存密码是不安全的。
max 的回答很好,只是有时会失败。
例如,当输入字符串为'my'时,return值是一个长度为15而不是16的字符串。这是因为return值的首字符为0 . 试试看
select old_password('my');
确认这一点。
补救措施是将 lpad() 函数应用于 hex(nr) 和 hex(nr2) -- 以下行
SET output = LOWER(CONCAT(HEX(nr), HEX(nr2)));
应该改为
SET output = LOWER(CONCAT(LPAD(HEX(nr),8,'0'), LPAD(HEX(nr2),8,'0')));
我在这里使用的是遗留代码库,该代码库目前使用 OLD_PASSWORD()
作为简单的哈希函数。此代码库现在需要连接到数据库 运行 MySQL 5.7.
PASSWORD()
的等价物似乎是:UPPER(SHA1(UNHEX(SHA1(password))))
。
是否有与OLD_PASSWORD()
类似的等价物?
似乎没有等效于使用 MySQL 函数的 OLD_PASSWORD()
,除非服务器允许设置全局变量。通过执行查询 SET @@global.old_passwords = 1;
,作为具有超级权限的用户,PASSWORD()
函数然后使用 OLD_PASSWORD()
算法散列密码。
如果像我们上面的例子一样,您没有超级用户(Google CloudSQL 不支持它们),则需要替换算法。以下是不同语言的替换:
免责声明:MySQL的旧密码在现代安全中起作用are a joke,应该不尽可能使用;这些算法一团糟。
我试图直接在 SQL 中为 OLD_PASSWORD 编写一个替换用户定义的函数,它似乎可以正常工作。该代码是在 post.
中找到的 PHP 版本的翻译DROP FUNCTION IF EXISTS OLD_PASSWORD;
DELIMITER $$
CREATE FUNCTION OLD_PASSWORD (input BLOB)
RETURNS CHAR(16)
DETERMINISTIC
BEGIN
DECLARE nr BIGINT;
DECLARE nr2 BIGINT;
DECLARE ad BIGINT;
DECLARE inlen INT;
DECLARE i INT;
DECLARE b CHAR;
DECLARE tmp INT;
DECLARE output CHAR(16);
SET nr = 1345345333;
SET nr2 = 0x12345671;
SET ad = 7;
SET inlen = LENGTH(input);
SET i = 1;
IF (input = '' OR input IS NULL) THEN
RETURN input;
END IF;
WHILE i <= inlen DO
SET b = MID(input, i, 1);
IF b != ' ' AND b != '\t' THEN
SET tmp = ORD(b);
SET nr = nr ^ ((((nr & 63) + ad) * tmp) + ((nr << 8) & 0xFFFFFFFF));
SET nr2 = nr2 + (((nr2 << 8) & 0xFFFFFFFF) ^ nr);
SET ad = ad + tmp;
END IF;
SET i = i + 1;
END WHILE;
SET nr = nr & ((1 << 31) - 1);
SET nr2 = nr2 & ((1 << 31) - 1);
SET output = LOWER(CONCAT(LPAD(HEX(nr),8,'0'), LPAD(HEX(nr2),8,'0')));
RETURN output;
END$$
DELIMITER ;
希望这对您有所帮助。但注意:以这种格式保存密码是不安全的。
max 的回答很好,只是有时会失败。
例如,当输入字符串为'my'时,return值是一个长度为15而不是16的字符串。这是因为return值的首字符为0 . 试试看
select old_password('my');
确认这一点。
补救措施是将 lpad() 函数应用于 hex(nr) 和 hex(nr2) -- 以下行
SET output = LOWER(CONCAT(HEX(nr), HEX(nr2)));
应该改为
SET output = LOWER(CONCAT(LPAD(HEX(nr),8,'0'), LPAD(HEX(nr2),8,'0')));