난스 작성 및 사용 방법
저는 웹사이트를 운영하고 있는데, 게임을 하는 횟수에 따라 점수를 주는 점수 제도가 있습니다.
해싱을 사용하여 스코어링을 위한 http 요청의 무결성을 증명하기 때문에 사용자는 아무것도 변경할 수 없습니다.그러나 내가 우려한 대로 누군가 그것을 변경할 필요가 없다는 것을 알게 되었고, 단지 높은 점수를 받아 http 요청, 헤더 등을 복제할 필요가 있었습니다.
전에는 이 공격으로부터 보호하는 것이 금지되어 있었습니다.그것은 가능성이 낮다고 여겨졌기 때문입니다.하지만, 그 일이 일어난 지금, 나는 할 수 있다.이 http 요청은 플래시 게임에서 생성되어 php에 의해 검증되고 php가 데이터베이스에 입력됩니다.
난스가 이 문제를 해결할 것이라고 확신하지만, 그것들을 어떻게 구현해야 할지 정확히 모르겠다.난스 시스템을 설정하는 일반적이고 안전한 방법은 무엇입니까?
사실 꽤 쉽게 할 수 있는...이 기능을 제공하는 라이브러리가 몇 가지 있습니다.
직접 쓰고 싶다면 아주 간단합니다.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학년 학생이 메시지를 해독할 수 있을 정도로 메시지의 기밀성이 파괴됩니다).
난제를 사용하는 세 가지 주요 학파가 있습니다.
- 하지 않도록 하는 것도 ).카운터를 늘리면서 재사용하지 않도록 주의해 주세요(송신측과 수신측용으로 다른 카운터를 사용하는 것도 의미합니다).각」의 「Nonce」의 「Nonce」를 격납해, 「」의 「Nonce」의 「Nonce」의 「Nonce」의 「Nonce」의 「Nonce」의 「Nonce」의 「Nonce」로부터 하지 않게 됩니다).
1
를 참조해 주세요. - 스테이트풀 랜덤 난스랜덤 난스를 생성하여 나중에 검증할 수 있도록 기억한다.이것은 CSRF 공격을 물리치기 위해 사용하는 전략으로, 여기서 요구하는 것에 가까운 것으로 들립니다.
- 큰 상태 비저장 랜덤 난스.안전한 난수 생성기를 사용하면 평생 난수를 두 번 반복하지 않을 수 있습니다.이는 NaCl이 암호화를 위해 사용하는 전략입니다.
이 점을 염두에 두고 주요 질문은 다음과 같습니다.
- 위의 생각들 중 당신이 해결하려는 문제와 가장 관련이 있는 학교는 어디입니까?
- 난스는 어떻게 생성합니까?
- 난스를 어떻게 검증하고 있습니까?
난스 생성
임의의 난스에 대한 질문 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
'source' 카테고리의 다른 글
Vuejs: 루트 변경 전 확인 대화 상자 표시 (0) | 2023.02.07 |
---|---|
$scope 사용방법$watch와 $watch입니다.$Apply in AngularJS? (0) | 2023.02.07 |
이 'dev.azure.com' 원격 URL의 조직 이름을 확인할 수 없습니다. (0) | 2023.02.07 |
"this" vs $scope in AngularJS 컨트롤러 (0) | 2023.02.07 |
Python 모듈 소스의 위치를 찾으려면 어떻게 해야 합니까? (0) | 2023.02.07 |