如何在php中加密mysql密码(或如何击败自动代码扫描器红旗)

时间:2009-12-29 22:08:28

标签: php mysql encryption connection-string

管理层再次罢工。

我应该如何满足将要读取我的php源码并将我的MySQL连接字符串标记为红色的代码扫描程序?

  • Linux服务器(即将成为Sun)
  • php 4.2(即将成为最新版本)
  • MySQL数据库
  • 防火墙外的DMZ中的服务器
  • 只读MySQL帐户
  • 数据库中没有单个非公开信息字节

我必须在连接字符串中加密我的MySQL密码,除了它将被自动代码测试解决方案标记为红色。管理层对笔测试的概念着迷,而不理解它。

我完全清楚,加密文件中的密码并不是更安全,并采取所有其他措施,但如果我不遵守,我的网站将会被删除。我知道这会伤害性能,但这个网站并不那么受欢迎,而且无论如何都不是一个庞大的数据库驱动的应用程序。

我的尝试:

//encrypt and decrypt are functions I stole wholesale off of the php.net manual
...
$SuperSecure[0] = array(encrypt("test"), encrypt("test")); //dev
...
$dbcnx = mysql_connect('localhost', decrypt($SuperSecure[0][0]), decrypt($SuperSecure[0][1]));

有更好的方法吗?更重要的是,我错过了什么,这实际上是必要的吗?

编辑:我再也不能打国民了。如果我忽略了这个指令,我的网站就会失败,失去我的工作是愚蠢的。我只是尽可能轻松地(并且性能影响最小)这样做。

8 个答案:

答案 0 :(得分:2)

您可以使用rot13来混淆(不加密)密码

答案 1 :(得分:2)

你不能在php.ini文件中定义默认的mysql主机,用户名和密码吗?然后mysql_connect函数看起来像:

`mysql_connect();`

除非黑客拥有您的php.ini文件,否则他们将无法访问用户名或密码。即使他们将功能更改为echo。当然他们可以回应指令,但我认为它已经足够混淆了,因为除了作为服务器文件的php.ini之外,在任何源文件中都找不到密码。

鉴于,如果有人做了phpinfo();,它也会在普通网站上显示,但它仍然有效。


此解决方案与另一个答案提供的ODBC解决方案非常相似。它还有一个缺陷,如果扫描程序检查你的php.ini文件,它将最终变成红色标记。


如果您想同时取笑它,我建议您在需要连接之前随机将mysql代码的片段放在随机文件中。 AKA

的index.php

Global $password;
$password = "S";

RandomFile.php

Global $password;
$password .= "T";

RandomFile2.php

Global $password;
$password .= "A";

RandomFile3.php

Global $password;
$password .= "CK";

RandomFile4.php

Global $password;
mysql_connect($host, $username, $password."Overflow");

答案 2 :(得分:2)

XOR!古老的一次性垫的基础。它是合法的加密,让你看起来更温和然后rot13()和任何有能力的人应该能够弄明白。与此同时,没有人会贪图密码。

<?
$pass = 'foobar';
$key = 'monkey';
$secret = $pass XOR $key;
$list = array($key, $secret);
foreach($list as $x) {
    print "Keypart: ";
    print implode(unpack('H*',$x));
    print "\n";
}
?>

Aaand我突然讨厌PHP如何做数组...现在,拿出那个......

的输出
<?
#Keypart: 6d6f6e6b6579
#Keypart: 666f6f626172

$secret = '666f6f626172';
$key = '6d6f6e6b6579';
$pass = pack('H*', $key) XOR pack('H*', $secret);
print "$pass\n";
?>

第一部分是您的加密生成器,第二部分是您必须放入程序中的内容。唯一的规则是,您对密码进行异或的字节串应该与密码的长度相同。如果不是,它可能不会做任何不需要的事情,但我不想构建一个测试用例。

答案 3 :(得分:1)

这是不必要的,因为你只是模糊了密码。拥有源代码的任何人都可以登录数据库,因为您的PHP脚本必须知道decrypt才能获得原始密码。

示例

假设您的密码是一个数字,例如42encrypt是一个乘以2的函数,而decrypt则相反。

然后,您将84存储在某处的代码中。但是,PHP还必须知道decrypt函数,并在连接到数据库之前将其转换为42。因此,由于您需要的所有内容都必须放在PHP文件中,因此混淆必要的信息毫无意义。

一些拥有源代码的邪恶黑客总是可以用mysql_connect替换代码示例中的echo并获取纯文本密码......

轻松混淆

也许只需在代码中使用"t"."e"."s"."t"而不是"test"来绕过密码检测就足够了......

答案 4 :(得分:1)

如果您不想直接将密码写入mysql_connect,为什么不写下以下内容:

$username = 'test';
$password = 'test';
mysql_connect('localhost', $username, $password);

在不知道扫描仪有多聪明的情况下,你真的无法分辨出什么不足以引起任何标志。

答案 5 :(得分:0)

您可以使用ODBC连接来访问数据库。 ODBC抽象层将其连接属性存储在单独的文件中(在UnixODBC中,它是/etc/odbc.ini和〜/ .odbc.ini)。这样,系统DSN就可以知道如何访问数据库,并且您的脚本将依赖它。

我建议谨慎使用ODBC,因为它无法访问直接MySQL连接所做的一些更复杂的函数和查询。

答案 6 :(得分:0)

我可能会忽略这一点,但让我问这个。

为什么不将mysql连接信息存储在运行时包含的某种形式的配置文件中,并使用某种形式的数据库抽象,而不是使用mysql_connects和处理数据库连接的其他遗留方法来编写代码?

我会发现您的自动代码扫描解决方案会读取纯文本ini文件或xml ini文件以及某些框架(如Zend)使得处理这些类型的配置文件非常容易,因此您的密码是不会分散在您的代码中,也不会随时访问网页......

听起来你已经采取了所有其他措施(网络外的服务器,只有所需的私有安全mysql帐户)。我是在误解你在做什么,还是有理由避免这里的最佳做法?

此致

答案 7 :(得分:0)

从第一天起就使用 Windows 作为服务器,不知道我的方式是否从一开始就错了,但是在注册表中存储凭据(并从中读取)是有效的,而且我一直在这样做。 这是我的片段:

$Root = HKEY_CURRENT_USER;


$key = "Software\MyApp1";

if (!($registry = @reg_open_key($Root, $key))) {
    throw new Exception("Valid Credential not found.");
}else{
    $user = reg_enum_key($registry, 0);
    $passw = reg_enum_key($registry, 1);
}

reg_close_key($registry);