source

난스 작성 및 사용 방법

manycodes 2023. 2. 7. 00:05
반응형

난스 작성 및 사용 방법

저는 웹사이트를 운영하고 있는데, 게임을 하는 횟수에 따라 점수를 주는 점수 제도가 있습니다.

해싱을 사용하여 스코어링을 위한 http 요청의 무결성을 증명하기 때문에 사용자는 아무것도 변경할 수 없습니다.그러나 내가 우려한 대로 누군가 그것을 변경할 필요가 없다는 것을 알게 되었고, 단지 높은 점수를 받아 http 요청, 헤더 등을 복제할 필요가 있었습니다.

전에는 이 공격으로부터 보호하는 것이 금지되어 있었습니다.그것은 가능성이 낮다고 여겨졌기 때문입니다.하지만, 그 일이 일어난 지금, 나는 할 수 있다.이 http 요청은 플래시 게임에서 생성되어 php에 의해 검증되고 php가 데이터베이스에 입력됩니다.

난스가 이 문제를 해결할 것이라고 확신하지만, 그것들을 어떻게 구현해야 할지 정확히 모르겠다.난스 시스템을 설정하는 일반적이고 안전한 방법은 무엇입니까?

사실 꽤 쉽게 할 수 있는...이 기능을 제공하는 라이브러리가 몇 가지 있습니다.

  1. PHP 난스 라이브러리
  2. OpenID 난스 라이브러리

직접 쓰고 싶다면 아주 간단합니다.WikiPedia 페이지를 시작점으로 사용하여 의사 코드:

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

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%는 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;
}

난스는 벌레의 통이다.

아니요, 실제로 여러 CASER 엔트리의 동기 중 하나는 스트림 암호에 기초한 인증된 암호화 스킴을 설계하고 난스 재사용에 대한 내성이 있는 것입니다.(예를 들어 난스를 AES-CTR에서 재사용하면 프로그래밍 1학년 학생이 메시지를 해독할 수 있을 정도로 메시지의 기밀성이 파괴됩니다).

난제를 사용하는 세 가지 주요 학파가 있습니다.

  1. 하지 않도록 하는 것도 ).카운터를 늘리면서 재사용하지 않도록 주의해 주세요(송신측과 수신측용으로 다른 카운터를 사용하는 것도 의미합니다).각」의 「Nonce」의 「Nonce」를 격납해, 「」의 「Nonce」의 「Nonce」의 「Nonce」의 「Nonce」의 「Nonce」의 「Nonce」의 「Nonce」로부터 하지 않게 됩니다).1를 참조해 주세요.
  2. 스테이트풀 랜덤 난스랜덤 난스를 생성하여 나중에 검증할 수 있도록 기억한다.이것은 CSRF 공격을 물리치기 위해 사용하는 전략으로, 여기서 요구하는 것에 가까운 것으로 들립니다.
  3. 큰 상태 비저장 랜덤 난스.안전한 난수 생성기를 사용하면 평생 난수를 두 번 반복하지 않을 수 있습니다.는 NaCl이 암호화를 위해 사용하는 전략입니다.

이 점을 염두에 두고 주요 질문은 다음과 같습니다.

  1. 위의 생각들 중 당신이 해결하려는 문제와 가장 관련이 있는 학교는 어디입니까?
  2. 난스는 어떻게 생성합니까?
  3. 난스를 어떻게 검증하고 있습니까?

난스 생성

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

  • random_bytes() PHP 7+ 프로젝트용
  • paragonie/random_compat, PHP 5 폴리필:random_bytes()
  • ircmaxell/RandomLib - 랜덤성 유틸리티의 스위스 군용 나이프. 랜덤성을 다루는 대부분의 프로젝트(예: fir password reset)는 자체 롤 대신 사용을 고려해야 합니다.

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

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

그리고.

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

난스 검증

스테이트풀

스테이트풀 난스는 간단하고 권장됩니다.

$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 lookup (메모캐시 룩업)

스테이트리스(여기에는 용이 있습니다)

이것은 해결하기 어려운 문제입니다.리플레이 공격을 막기 위한 방법이 필요하지만 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 Web 토큰의 비표준 버전임을 알 수 있습니다.

(댓글에서 말씀드린) 하나의 옵션은 게임 플레이를 녹화하여 안전한 환경에서 재생하는 것입니다.

또, 랜덤으로, 또는 특정의 특정의 시간에 데이터를 기록해, 나중에 서버상에서 검증할 수 있습니다(예를 들면, 라이브가 갑자기 1%에서 100%로 되어 있거나, 부정행위를 나타내는 스코어가 1~1000으로 되어 있는 등).충분한 데이터가 있으면 부정행위를 하는 사람이 그것을 속이는 것은 불가능할 수도 있다.그리고 물론, 엄중한 금지를 실시합니다. :)

이 매우 단순한 난스는 1000초(16분)마다 변경되어 같은 어플리케이션에서 데이터를 투고하고 있는 XSS를 회피하기 위해 사용할 수 있습니다.(예를 들어 javascript를 사용하여 데이터를 투고하고 있는 단일 페이지 어플리케이션의 경우).포스트와 수신측에서 동일한 시드 및 난스 제너레이터에 액세스할 수 있어야 합니다.)

function makeNonce($seed,$i=0){
    $timestamp = time();
    $q=-3; 
    //The epoch time stamp is truncated by $q chars, 
    //making the algorthim to change evry 1000 seconds
    //using q=-4; will give 10000 seconds= 2 hours 46 minutes usable time

    $TimeReduced=substr($timestamp,0,$q)-$i; 

    //the $seed is a constant string added to the string before hashing.    
    $string=$seed.$TimeReduced;
    $hash=hash('sha1', $string, false);
    return  $hash;
}   

그러나 이전 난스를 확인함으로써 사용자는 최악의 경우 16.6분, 최선의 경우 33분 이상 기다린 경우에만 문제가 발생합니다.$q=-4를 설정하면 사용자에게 최소 2.7시간이 주어집니다.

function checkNonce($nonce,$seed){
//Note that the previous nonce is also checked giving  between 
// useful interval $t: 1*$qInterval < $t < 2* $qInterval where qInterval is the time deterimined by $q: 
//$q=-2: 100 seconds, $q=-3 1000 seconds, $q=-4 10000 seconds, etc.
    if($nonce==$this->makeNonce($seed,0)||$nonce==$this->makeNonce($seed,1))     {
         //handle data here
         return true;
     } else {
         //reject nonce code   
         return false;
     }
}

$seed는 프로세스에서 사용되는 임의의 함수 호출 또는 사용자 이름 등이 될 수 있습니다.

부정행위를 예방하는 것은 불가능하다.더 어렵게 만들 수 있어요.

PHP Nonce Library를 찾고 있는 경우: ircmaxwell이 제공한 첫 번째 라이브러리를 사용하지 않는 것이 좋습니다.

웹 사이트의 첫 번째 코멘트는 설계 결함을 설명합니다.

난스는 특정 기간 동안 유효합니다. 즉, 사용자가 창 끝에 가까워질수록 양식을 제출할 시간이 단축됩니다(아마도 1초 미만).

올바르게 정의된 라이프 타임을 사용하여 Nonce를 생성하는 방법을 찾는 경우 NonceUtil-PHP를 참조하십시오.

면책사항:NonceUtil-PHP의 저자입니다.

언급URL : https://stackoverflow.com/questions/4145531/how-to-create-and-use-nonces

반응형