복붙노트

논스를 생성하고 사용하는 방법

PHP

논스를 생성하고 사용하는 방법

나는 웹 사이트를 운영하고 있으며 게임을하는 횟수에 대한 점수를주는 채점 시스템이 있습니다.

그것은 해싱을 사용하여 점수 요청에 대한 http 요청의 무결성을 증명하므로 사용자는 아무 것도 변경할 수 없지만 일어날 수 있다고 생각되면 누군가는 변경하지 않아도되고 높은 점수를 받아야한다고 생각한 것입니다. http 요청, 헤더 및 모두.

이전에는 가능성이 희박하기 때문에이 공격으로부터 보호 할 수 없었습니다. 그러나 이제는 그런 일이 일어났습니다. http 요청은 플래시 게임에서 시작된 다음 php가 유효성을 검사하고 php가 데이터베이스에 입력합니다.

나는 논스가이 문제를 해결할 것이라고 확신하지만, 어떻게 구현해야하는지 정확하게 알지 못한다. nonce 시스템을 설정하는 공통적이고 안전한 방법은 무엇입니까?

해결법

  1. ==============================

    1.사실 꽤 쉽게 할 수 있습니다 ... 거기에 당신을 위해 그것을 할 몇 가지 라이브러리가 있습니다 :

    사실 꽤 쉽게 할 수 있습니다 ... 거기에 당신을 위해 그것을 할 몇 가지 라이브러리가 있습니다 :

    또는 직접 작성하려는 경우 매우 간단합니다. WikiPedia 페이지를 점프 포인트로 사용하여 의사 코드 :

    서버 측에서 두 개의 클라이언트 호출 가능 함수가 필요합니다.

    getNonce() {
        $id = Identify Request //(either by username, session, or something)
        $nonce = hash('sha512', makeRandomString());
        storeNonce($id, $nonce);
        return $nonce to client;
    }
    
    verifyNonce($data, $cnonce, $hash) {
        $id = Identify Request
        $nonce = getNonce($id);  // Fetch the nonce from the last request
        removeNonce($id, $nonce); //Remove the nonce from being used again!
        $testHash = hash('sha512',$nonce . $cnonce . $data);
        return $testHash == $hash;
    }
    

    그리고 클라이언트 측에서 :

    sendData($data) {
        $nonce = getNonceFromServer();
        $cnonce = hash('sha512', makeRandomString());
        $hash = hash('sha512', $nonce . $cnonce . $data);
        $args = array('data' => $data, 'cnonce' => $cnonce, 'hash' => $hash);
        sendDataToClient($args);
    }
    

    makeRandomString 함수는 실제로 난수 나 문자열을 반환하면됩니다. 무작위성이 좋을수록 보안 성이 좋아집니다. 해시 함수로 바로 전달되므로 구현 세부 정보는 요청에서 요청까지 중요하지 않습니다. 클라이언트 버전과 서버 버전이 일치 할 필요는 없습니다. 실제로, 100 %와 일치해야하는 유일한 비트는 hash ( 'sha512', $ nonce. $ cnonce. $ data);에서 사용되는 해시 함수입니다. 다음은 합리적으로 안전한 makeRandomString 함수의 예입니다.

    function makeRandomString($bits = 256) {
        $bytes = ceil($bits / 8);
        $return = '';
        for ($i = 0; $i < $bytes; $i++) {
            $return .= chr(mt_rand(0, 255));
        }
        return $return;
    }
    
  2. ==============================

    2.아니요, 실제로 여러 CAESAR 항목의 동기 중 하나는 인증 된 암호화 체계를 설계하는 것이 었습니다. 바람직하게는 스트림 암호를 기반으로하며 nonce 재사용에 강합니다. 예를 들어, nonce를 AES-CTR로 재사용하면 첫 해 프로그래밍 학생이 해독 할 수있는 정도로 기밀성을 파괴합니다.

    아니요, 실제로 여러 CAESAR 항목의 동기 중 하나는 인증 된 암호화 체계를 설계하는 것이 었습니다. 바람직하게는 스트림 암호를 기반으로하며 nonce 재사용에 강합니다. 예를 들어, nonce를 AES-CTR로 재사용하면 첫 해 프로그래밍 학생이 해독 할 수있는 정도로 기밀성을 파괴합니다.

    nonces와 함께 생각의 세 가지 주요 학교가 있습니다 :

    그래서이를 염두에두고 질문 할 주요 질문은 다음과 같습니다.

    랜덤 nonce에 대한 질문 2의 대답은 CSPRNG를 사용하는 것입니다. PHP 프로젝트의 경우 다음 중 하나를 의미합니다.

    이 두 가지는 도덕적으로 동일합니다.

    $factory = new RandomLib\Factory;
    $generator = $factory->getMediumStrengthGenerator();
    $_SESSION['nonce'] [] = $generator->generate(32);
    

    $_SESSION['nonce'] []= random_bytes(32);
    

    Stateful nonces는 쉽고 권장합니다 :

    $found = array_search($nonce, $_SESSION['nonces']);
    if (!$found) {
        throw new Exception("Nonce not found! Handle this or the app crashes");
    }
    // Yay, now delete it.
    unset($_SESSION['nonce'][$found]);
    

    array_search ()를 데이터베이스 또는 memcached 조회 등으로 대체하십시오.

    이것은 어려운 문제입니다. 재생 공격을 막기 위해서는 어떤 방법이 필요하지만 서버는 각 HTTP 요청 후에 총 기억 상실증이 있습니다.

    유일한 정상적인 솔루션은 재생 공격의 유용성을 최소화하기 위해 만료 날짜 / 시간을 인증하는 것입니다. 예 :

    // Generating a message bearing a nonce
    $nonce = random_bytes(32);
    $expires = new DateTime('now')
        ->add(new DateInterval('PT01H'));
    $message = json_encode([
        'nonce' => base64_encode($nonce),
        'expires' => $expires->format('Y-m-d\TH:i:s')
    ]);
    $publishThis = base64_encode(
        hash_hmac('sha256', $message, $authenticationKey, true) . $message
    );
    
    // Validating a message and retrieving the nonce
    $decoded = base64_decode($input);
    if ($decoded === false) {
        throw new Exception("Encoding error");
    }
    $mac = mb_substr($decoded, 0, 32, '8bit'); // stored
    $message = mb_substr($decoded, 32, null, '8bit');
    $calc = hash_hmac('sha256', $message, $authenticationKey, true); // calcuated
    if (!hash_equals($calc, $mac)) {
        throw new Exception("Invalid MAC");
    }
    $message = json_decode($message);
    $currTime = new DateTime('NOW');
    $expireTime = new DateTime($message->expires);
    if ($currTime > $expireTime) {
        throw new Exception("Expired token");
    }
    $nonce = $message->nonce; // Valid (for one hour)
    

    신중한 관찰자는 이것이 기본적으로 비표준 JSON 웹 토큰의 변형임을 알 수 있습니다.

  3. ==============================

    3.한 가지 옵션은 게임 플레이를 기록하고 안전한 환경에서 재생하는 것입니다.

    한 가지 옵션은 게임 플레이를 기록하고 안전한 환경에서 재생하는 것입니다.

    다른 하나는 무작위로 또는 특정 시간에 서버에서 유효성을 검사하는 데 사용할 수있는 겉으로보기에 무해한 데이터를 기록하는 것입니다 (예 : 갑자기 라이브가 1 %에서 100 %로 이동하거나 치트를 나타내는 1에서 1000으로 점수 매김). ). 충분한 데이터가 있으면 사기범이 가짜로 만들려고 시도하는 것이 타당하지 않을 수 있습니다. 그리고 무거운 금지 구현 :) 물론.

  4. ==============================

    4.부정 행위를 막는 것은 불가능합니다. 당신은 더 어렵게 만들 수 있습니다.

    부정 행위를 막는 것은 불가능합니다. 당신은 더 어렵게 만들 수 있습니다.

    누군가가 여기에 온다면 PHP Nonce Library를 찾으십시오 : 나는 ircmaxwell에 의해 주어진 첫번째 것을 사용하지 않을 것을 권장합니다.

    웹 사이트에 대한 첫 번째 의견은 디자인 결함을 설명합니다.

    NonceUtil-PHP를 잘 정의 된 수명으로 Nonce를 생성하는 방법을 찾고 있다면.

  5. from https://stackoverflow.com/questions/4145531/how-to-create-and-use-nonces by cc-by-sa and MIT license