nonce를 만들고 사용하는 방법
저는 웹 사이트를 운영하고 게임을 한 횟수에 따라 점수를 점수 시스템이 있습니다.
해싱을 사용하여 점수에 대한 http 요청의 무결성을 증명하는 사용자는 아무것도 없습니다. 그러나 어느 누군가가 있다고 말하는 것이 있다고 주장합니다. http 요청, 헤더 및 모두.
이전에는이 공격이 가능성이없는 것들이 공격으로부터 보호하는 것이 금지됩니다. 그러나 이제는 그렇게 할 수 있습니다. http 요청은 플래시 게임에서 시작된 다음 php에 의해 유효성이 검사되고 php는이를 데이터베이스에 입력합니다.
확신하지만 구현 방법을 정확히 모르겠습니다. nonce 시스템을 설정하는 일반적이고 안전한 방법은 무엇입니까?
당신을 위해 할 수있는 라이브러리가 있습니다.
또는 직접 작성하고 매우 간단합니다. 은 위키 사용 피 디아 페이지를 의사 코드에서 포인트 떨어져 점프로 :
서버 측에는 두 개의 클라이언트 호출이 가능합니다.
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;
}
Nonce는 웜 캔입니다.
아니요, 실제로 여러 개의 CAESAR 항목 에 대한 다수의 중 하나는 무리에 저항하는 인증 된 암호화 체계를 설계하는 것이 었습니다. (예를 들어, 임시 값을 AES-CTR 학생으로 보완하면 1 학년 프로그래밍이 해독 할 수 있습니다. 메시지의 기밀성이 손상됩니다.)
논스를 사용하는 세 가지 주요 사고 학교가 있습니다.
- 대칭 키 암호화 : 증가하는 카운터를 사용하고 절대하지 않습니다. (즉, 각 요청이 요청을 시작하지 않는 것이 아니라는 것을 의미합니다
1
). - 상태 저장 무작위 임시 값. 무작위 임시 값을 생성 한 다음 나중에 유효성을 검사하기 위해 기억합니다. 이것은 CSRF 공격을 물리 치는 데 사용되는 전략이며, 여기에서 요구하는 것입니다.
- 큰 상태 비 저장 랜덤 임시 값. 안전한 난수 생성기를 사용하면 평생 동안 nonce를 두 번 반복하지 않을 것입니다. 이것은 암호화를 위해 NaCl 에서 사용하는 전략 입니다.
주요 질문은 다음과 질문합니다.
- 위의 생각 학교 중 해결하려는 문제와 가장 관련이있는 것은 무엇입니까?
- 임시 값을 어떻게 생성하고 있습니까?
- nonce를 어떻게 유전하고 있습니까?
Nonce 생성
임의의 임시 값에 대한 질문 2에 대한 대답은 CSPRNG를 사용하는 것입니다. PHP 프로젝트의 경우 다음 중 하나를 의미합니다.
random_bytes()
PHP 7+ 프로젝트 용- paragonie / random_compat , PHP 5 폴리 필
random_bytes()
- ircmaxell / RandomLib , 임의성 (예 : 장식적인 암호)을 다루는 대부분의 프로젝트에서 자체 롤링 대신 사용을하는 임의성 유틸리티의 스위스 군용 칼입니다.
이 두 개의 도덕적으로 동일합니다.
$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 조회 등으로 자유롭게 대체하십시오 .
무국적 (여기 드래곤이있다)
이것은 해결하기 어려운 문제입니다. 리플레이 공격을 방지 할 수있는 방법이 필요하지만 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 웹 토큰 의 비표준 호환 변형이라는 점에 주목할 것입니다 .
한 가지 옵션 (댓글에서 언급 했음)은 게임 플레이를 녹화하고 안전한 환경에서 재생하는 것입니다.
다른 한 가지는 무작위로 또는 특정 시간에 무해 해 보이는 데이터를 기록하는 것입니다. 나중에 서버에서이를 검증하는 데 사용할 수 있습니다 (예 : 갑자기 라이브가 1 %에서 100 %로 변경되거나 치트를 나타내는 1에서 1000까지의 점수) ). 데이터가 충분하면 사기꾼이 가짜를 시도하는 것이 불가능할 수 있습니다. 그리고 물론 무거운 금지를 구현하십시오 :).
이 매우 간단한 임시 값은 1000 초 (16 분)마다 변경되며 동일한 응용 프로그램에서 데이터를 게시하는 XSS를 방지하는 데 사용할 수 있습니다. (예를 들어, 자바 스크립트를 통해 데이터를 게시하는 단일 페이지 애플리케이션에있는 경우. 게시 및 수신 측에서 동일한 시드 및 임시 생성기에 액세스 할 수 있어야합니다.)
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 라이브러리를 찾고있는 경우 : ircmaxwell이 제공 한 첫 번째 라이브러리를 사용하지 않는 것이 좋습니다 .
웹 사이트의 첫 번째 댓글은 디자인 결함을 설명합니다.
임시 값은 특정 시간 창에 적합합니다. 즉, 사용자가 해당 창 끝에 가까워 질수록 양식을 제출하는 데 걸리는 시간이 1 초 미만일 수 있습니다.
수명이 잘 정의 된 Nonce를 생성하는 방법을 찾고 있다면 NonceUtil-PHP를 살펴보십시오 .
면책 조항 : 저는 NonceUtil-PHP의 저자입니다.
참고 URL : https://stackoverflow.com/questions/4145531/how-to-create-and-use-nonces
'ProgramingTip' 카테고리의 다른 글
페이지 새로 고침시 Vuex 상태 (0) | 2020.11.28 |
---|---|
Mercurial에서 기본 diff 도구를 사용합니까? (0) | 2020.11.28 |
Java Generics-Bridge 방법? (0) | 2020.11.28 |
실시간 공동 편집-어떻게 작동 작동? (0) | 2020.11.28 |
Java Primitives 범위 계산 (0) | 2020.11.28 |