使用PHP轻松加密和解密

使用PHP轻松加密和解密,php,encryption,Php,Encryption,我的PHP应用程序使用如下URL: http://domain.com/userid/120 http://domain.com/userid/121 键和URL的结尾基本上是MySQL数据库表的主键 我不希望这个不断增加的数字被公开,我也不希望有人仅仅通过交互Id就能抓取用户配置文件 所以我想加密这个Id以便于再次解密。绳子不应该再长了 最好的加密方法是什么 隐藏URL将永远无法保护它。它使阅读变得更加困难,但操纵起来并不难。您可以使用十六进制数字表示法或类似的方法来模糊它。不管怎样,那些能

我的PHP应用程序使用如下URL:

http://domain.com/userid/120
http://domain.com/userid/121
键和URL的结尾基本上是MySQL数据库表的主键

我不希望这个不断增加的数字被公开,我也不希望有人仅仅通过交互Id就能抓取用户配置文件

所以我想加密这个Id以便于再次解密。绳子不应该再长了


最好的加密方法是什么

隐藏URL将永远无法保护它。它使阅读变得更加困难,但操纵起来并不难。您可以使用十六进制数字表示法或类似的方法来模糊它。不管怎样,那些能读十六进制的人可以在几秒钟内更改您的URL:

$hexId = dechex($id); // to hex
$id = hexdec($hexId); // from hex
一个更好的方法(从可用性和SEO的角度)是使用一个独特的短语,而不是一个模糊的ID。在这种情况下,用户的用户名似乎是一个理想的解决方案,也是不可猜测的


这就是说,如果您不想使用这种方法,您可以使用用户用户名的散列(也许)将其与其他详细信息一起存储在数据库中。因此,您可以直接查找该字段。(也就是说,对URL进行加密和解密可能有些过分。)

为每个用户生成一个唯一的字符串,并在URL中使用它


http://domain.com/user/ofisdoifsdlfkjsdlfkj
而不是
http://domain.com/userid/121

简单模糊化:Base64使用 现在,您的应用程序将变成:
想要更多,再做一次,在周围加上一些字母


难以隐藏:使用任何使用库的加密方法。

最简单但功能强大的加密方法:使用密钥的XOR。 没有实际的性能下降

Base64表示不是加密!这是另一种说法


希望这能有所帮助。

您可以使用
base64\u encode
base64\u decode
功能对URL进行加密和解密

您有多种选择:

  • 在数据库中生成并存储标识符。这很好,因为您可以拥有保证唯一的可读密钥。这是不好的,因为它会导致数据库模式发生更改,并且每次要生成链接时都必须实际查询该表

  • 运行实际的基于密钥的加密,例如基于PHP的MCrypt。您可以访问功能强大的加密算法,但大多数安全算法倾向于输出比您期望的长得多的字符串。XOR实现了您想要的功能,但它并不阻止访问顺序值(鉴于数字的先验知识,确定键非常简单)

  • 运行基于哈希的验证:不要使用
    121
    作为标识符,而是使用
    121-a34df6
    ,其中
    a34df6
    121
    md5
    (或其他
    HMAC
    )的前六个字符和一个密钥。不是解码,而是提取
    121
    并重新计算这六个字符,以查看它们是否与用户发送的内容匹配。这不会隐藏
    121
    (它仍然在连字符前面),但在不知道密钥的情况下,访问者将无法生成六个字符来实际查看编号为
    121
    的文档

  • 将异或与洗牌一起使用:洗牌30位标识符中的位,然后应用异或。这使得XOR更难识别,因为洗牌模式也是隐藏的

  • 对按需密钥使用异或:使用
    fb37cde4-37b3
    作为密钥,其中第一部分是
    121
    md5('37b3'.SECRET)
    (或基于
    37b3
    和SECRET生成异或密钥的另一种方法)

不要使用base64,逆向工程很容易:如果
MTIx
121
,那么
MTIy
122


最终,您必须承认您的解决方案将不安全:不仅用户可能泄漏有效URL(通过其浏览器历史记录、HTTP引用或在Twitter上发布),而且您要求标识符只包含少量字符,这意味着可能发生暴力攻击(并且随着您开始拥有更多文档而变得更容易)。

我可能会说,实际上,为每个用户创建一个随机字符串并将其存储在您的数据库中比使用散列获取一个要好。如果您使用通用散列,则仍然很容易在所有页面上进行迭代;-)


我会在评论中写这篇文章,但还没有它的代表(还?)。

当用户单击不应该使用主键的链接时,您可以在会话中使用pkey并从该会话中获取它。请不要使用查询字符串…

我建议在url中使用用户名,如。它更像是web 2.0,你可以保密你的主密钥,并且不会通过加密/解密主密钥而使服务器过载。我真的在努力抵制说你做错了的冲动。首先,谁在乎用户配置文件是否可以爬网?谷歌无论如何都会找到他们,所以除了把他们放在登录后面(即使这样,想要得到信息的人也会得到)之外,没有什么真正的方法可以阻止它。其次,为什么要在url中使用id?为什么不使用唯一的用户名(用户名是唯一的,不是吗?)?它比数字有更多的语义含义,而且效率应该不会低很多(假设您在用户名列上设置了
UNIQUE
)。您如何区分简单加密和严格加密?@sandepan,简单容易解密,不使用密钥,但难解密。您如何区分易解密和难解密?;-)@维克托:在这种情况下,给定一个URL,简单的解码不需要额外的信息,很难解码