无会话的PHP验证码

无会话的PHP验证码,php,captcha,Php,Captcha,好的,这里有一个问题:在我正在工作的项目中,我们不能依赖服务器端会话来实现任何功能 问题是,防止自动提交的常见验证码解决方案需要会话存储字符串以匹配验证码 问题是-有没有办法不使用会话来解决问题?我想到的是提供隐藏表单字段,其中包含一些散列,以及captcha输入字段,这样服务器就可以将这两个值匹配在一起。但是,我们如何才能使这种方法安全,从而使其不易被用于破解验证码。您可以尝试在数据库中存储一组验证码。或者,这里有一个关于其他验证码方法的讨论: 一些非常有趣的技术,真的,请通读。使隐藏的输入字

好的,这里有一个问题:在我正在工作的项目中,我们不能依赖服务器端会话来实现任何功能

问题是,防止自动提交的常见验证码解决方案需要会话存储字符串以匹配验证码


问题是-有没有办法不使用会话来解决问题?我想到的是提供隐藏表单字段,其中包含一些散列,以及captcha输入字段,这样服务器就可以将这两个值匹配在一起。但是,我们如何才能使这种方法安全,从而使其不易被用于破解验证码。

您可以尝试在数据库中存储一组验证码。或者,这里有一个关于其他验证码方法的讨论:


一些非常有趣的技术,真的,请通读。

使隐藏的输入字段只是一个随机序列。将此随机数据与验证码信息一起存储在数据库中,以便您可以使用它查找正确的验证码


您还需要为生成的每个验证码设置较短的生存时间。最后,您可以在数据库中存储和跟踪每个验证码的尝试次数,并对其施加硬限制(3次猜测,这是永久性失败)。

如果没有持久状态服务器端,我看不到验证码有效

您的建议并不安全,因为攻击者可以轻松地发布自己的“隐藏字段”和匹配的验证码文本


为什么不从另一个可以具有持久状态的Web服务器上执行验证码呢?

我自己的想法,不知道它是否好:

1) 如果用户已登录,只需在其登录名上使用一些哈希函数并生成CAPTCHA

2) 若它是注册表单等,只需从表单字段中散列一些值(例如,当用户完成输入时,登录名),并通过ajax显示带有登录名散列的CAPTCHA

希望,这是可以理解的。:)

编辑: 没有AJAX: 注册的两个步骤:

在1时,我们收集登录信息等。提交后,我们直接登录到
?login=new\u login


在第2步,我们使用
GET[“login”]
隐藏输入,并在验证码图像中对其进行哈希-提交后,我们必须检查答案

您能否授予他们客户端证书以响应验证码调用?然后,一旦他们在浏览器中选择了该证书,它将与来自客户端的每次调用一起发送,并且可以用于身份验证,而无需会话和进一步的验证码调用。

以下是我对它的看法(sry,如果它看起来复杂):

  • 第页请求:

    • 生成一个随机字符串代码“abcdef”
    • 您可以使用一些预定义的密码对代码进行加密: $crypt=encrypt($captcha\u代码,“密码”)
  • 形式如下:

    • 图像链接被发送到浏览器“captcha.php?$crypt”
    • 隐藏输入的值设置为$crypt
  • php页面对加密文本进行解密,并生成图像

  • 用户提交一个带有代码“abcdaa”(和隐藏输入$crypt)的表单

  • 服务器验证encrypt('abcdaa')==$crypt
  • 编辑:
    加密函数需要是可逆的(解密),因为验证码图像生成器需要原始代码。

    这个解决方案怎么样?我在谷歌上找到了这篇“无会话PHP验证码”文章,我在我的一个项目中使用了它,它很简单,没有会话,而且是免费的。RC4有任何安全问题吗

    使用:将贪婪名称的文本字段作为“电子邮件”放入CSS隐藏的字段中(显示:无;可见性:隐藏;)

    当您必须清理表单时,只需检查该字段是否为空,是否由人发送(无法看到该字段,因此无法填充),或者是否由垃圾邮件发送者发送

    这就是为什么垃圾邮件发送者通常在发送表单之前用预定义的值填充页面中的所有字段。。。并且不会因为用户阅读验证码而打扰用户

    否则,依赖人类阅读,比如“在字段中写出单词“$word”的第一个$x字母:”

    然后,您只需将$x和$word发送到下一页并进行检查(当然,您可以将字段名称随机化以提高准确性)

    我记得phpBB论坛的插件依赖于这样一个事实:通常,垃圾邮件机器人会在
    字段中选择第一个可用选项(带有值);只需将其作为第一个选项
    是的,我是一个机器人。


    有很多方法可以防止垃圾邮件,利用一个机器人永远不会拥有的因素:想象会话或数据库的需要来自于需要将图像的GET与包含它的html页面协调,那么使用相同的代码嵌入验证码图像:[img src='data:image/jpeg;base64,'],使用随机salt对其文本进行散列,然后在一次GET中将随机salt和散列与图像一起发送到客户端


    回发时,将用户文本附加到salt,然后比较散列。只是想知道这有多安全…

    让验证码生成器返回一个图像,并使用salted散列或自定义散列作为答案(强调salted/custom)。让生成器将该哈希值推送到cookie中。然后,服务器可以根据cookie中的值进行验证。这不需要JavaScript,但如果禁用Cookie,则必须使用另一种技术。

    在帖子中自动填充验证码的UUID以及用户答案。简单的豌豆

    只要做一个数学验证码;)2+90 = ? 方程应该用图像表示,瞧;)

    带有验证的表单:
    $errorsucc = '';
    
    if (isset($_POST["captcha_check"])) {
    
        $code = str_decrypt($_POST["captcha_check"]);   
    
        if (empty($_POST['captcha_code'])) { 
            $errorsucc = '<p style="color:red">Please Enter the security code.</p>';
    
        } elseif(!( $code == $_POST['captcha_code'] && !empty($code) )) {
            $errorsucc = '<p style="color:red">Incorrect Code Entered.</p>';
    
        } else {
            $errorsucc = '<p style = "green">Nice, you entered the correct code.</p>';  
        }
    }
    
    $captcha = new CaptchaCode();
    $code = str_encrypt($captcha->generateCode(6));
    ?>
    
    <html>
        <title>Sessionless Captcha</title>
        <div style = "background: #e2e2e2; padding: 20px; width: 20%; box-shadow: 5px 5px #ccc;">
            <?php echo $errorsucc; ?>
            <form name="captchaform" method="post">
                <table border="0" cellpadding="4" cellspacing="0">
                    <tr><td valign="middle" align="left">Security Code:</td>
                        <td valign="middle" align="left"><img src="captcha_images.php?width=150&height=50&code=<?php echo $code?>" /></td>
                    </tr>
                    <tr><td valign="middle" align="left">Enter Code:</td>
                        <td valign="middle" align="left"><input id="captcha_code" name="captcha_code" style="width:150px" type="text" /></td>
                    </tr>
    
                    <tr><td valign="top" align="left">
                        </td>
                        <td valign="top" align="left">
                            <input border="0" type="submit" value="Submit" />   
                        </td>
                    </tr>
                </table>
                <input type="hidden" name="captcha_check" value="<?php echo $code?>" />
            </form>
        </div>
    </html>
    
    $errorsuch='';
    如果(isset($\u POST[“验证码检查”])){
    $code=str_decrypt($_POST[“验证码检查”]);
    如果(空($_POST['captcha_code']){
    $errorsucc='

    请输入安全代码。

    '; }elseif(!($code==$\u POST['captcha\u code']&&!empty($cod
    /* font size will be 75% of the image height */
        $font_size = $height * 0.75;
        $image = @imagecreate($width, $height) or die('Cannot initialize new GD image stream');
        /* set the colours */
        $background_color = imagecolorallocate($image, 255, 255, 255);
        $text_color = imagecolorallocate($image, 0, 26, 26);
        $noise_color = imagecolorallocate($image, 25, 89, 89);
        /* generate random dots in background */
        for( $i=0; $i<($width*$height)/3; $i++ ) {
            imagefilledellipse($image, mt_rand(0,$width), mt_rand(0,$height), 1, 1, $noise_color);
        }
        /* generate random lines in background */
        for( $i=0; $i<($width*$height)/150; $i++ ) {
            imageline($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $noise_color);
        }
        /* create textbox and add text */
        $textbox = imagettfbbox($font_size, 0, $this->font, $code) or die('Error in imagettfbbox function');
        $x = ($width - $textbox[4])/2;
        $y = ($height - $textbox[5])/2;
        imagettftext($image, $font_size, 0, $x, $y, $text_color, $this->font , $code) or die('Error in imagettftext function');
        /* output captcha image to browser */
        header('Content-Type: image/jpeg');
        imagejpeg($image);
        imagedestroy($image);