我的PHP应用程序使用以下URL:
http://domain.com/userid/120
http://domain.com/userid/121
URL的键和结尾基本上是MySQL数据库表的主键。
我不希望这个增加的数字公开,我也不希望有人能够通过交换ID来抓取用户配置文件。
所以我想加密这个Id,以便我可以轻松地再次解密它。字符串不应该长得多。
最好的加密方法是什么?
答案 0 :(得分:7)
简单模糊:Base64使用base64_encode
对其进行编码
现在,您的http://domain.com/userid/121变为:http://domain.com/userid/MTIx
想要更多,再做一遍,在它周围添加一些字母。
严格模糊:使用MCrypt库使用任何加密方法。
答案 1 :(得分:6)
更好的方法(从可用性和SEO角度来看)将使用唯一的短语而不是模糊的ID。在这种情况下,用户的用户名似乎是一个理想的解决方案,也是不可猜测的。
也就是说,如果你不想使用这种方法,你可以使用你存储在数据库中的用户用户名的哈希值(可能md5)以及其他详细信息。因此,您可以直接在该字段上进行查找。 (即:加密和解密部分URL可能有点过分。)
答案 2 :(得分:4)
您有多种选择:
在数据库中生成并存储标识符。这很好,因为你可以拥有保证唯一的可读密钥。这很糟糕,因为它会导致数据库架构更改,并且每次要生成链接时都必须实际查询该表。
运行基于密钥的实际加密,例如基于PHP的MCrypt。您可以访问强大的加密算法,但大多数安全算法往往会输出比您预期的更长的字符串。 XOR可以满足您的需求,但它不会阻止访问顺序值(鉴于数据的先验知识,关键很容易确定)。
运行基于哈希的验证:不使用121
作为您的标识符,而是使用121-a34df6
,其中a34df6
是md5
的前六个字符(或其他HMAC
)121
和密钥。您不是解码,而是提取121
并重新计算六个字符,以查看它们是否与用户发送的字符匹配。这不会隐藏121
(它仍然在连字符之前),但在不知道密钥的情况下,访问者将无法生成六个字符来实际查看编号为121
的文档。 / p>
使用XOR进行混洗:将30位标识符中的位混洗,然后应用XOR。这使得XOR难以识别,因为混洗模式也是隐藏的。
对按需键使用XOR:使用fb37cde4-37b3
作为键,其中第一部分是121
和md5('37b3'.SECRET)
的异或(或另一种生成XOR密钥基于37b3
和秘密)。
不要使用base64,反向工程很容易:如果MTIx
是121
,则MTIy
是122
...
最终,您必须接受您的解决方案不安全:用户不仅可以泄漏有效网址(通过浏览器历史记录,HTTP引用或在Twitter上发布),而且还要求标识符适合少量字符意味着可以进行暴力攻击(并且当您开始拥有更多文档时变得更容易)。
答案 3 :(得分:1)
最简单但功能最强大的加密方法:带有密钥的XOR。 http://en.wikipedia.org/wiki/XOR_cipher 没有实际的性能下降。
Base64表示不是加密!这是另一种说法相同的方式。
希望这有帮助。
答案 4 :(得分:0)
隐藏URL永远不会保护它。这使得阅读更难,但操作起来并不困难。您可以使用十六进制数字表示或类似的东西来模糊它。那些能读取十六进制的人可以在几秒钟内改变你的URL:
$hexId = dechex($id); // to hex
$id = hexdec($hexId); // from hex
答案 5 :(得分:0)
我可能会说,确实为每个用户创建一个随机字符串并将其存储在数据库中比使用哈希获取一个字符串更好。如果你使用一个公共哈希,它仍然很容易迭代所有页面; - )
我会在评论中写这个,但是没有它的代表(还有?)。
答案 6 :(得分:0)
当用户单击链接时,您不应使用主键,您可以在会话中使用pkey并从该会话中获取它。请不要使用查询字符串....
答案 7 :(得分:-1)
为每个用户生成一个唯一的字符串,并在您的网址中使用
http://domain.com/user/ofisdoifsdlfkjsdlfkj
代替http://domain.com/userid/121
答案 8 :(得分:-1)
您可以使用base64_encode
和base64_decode
功能加密和解密您的网址