いくつかのものをスケジュールし、識別子をスケジュールされたタスクにいくつかの異物に返すシステムがあります。推測できないユニークなトークンの生成
identifier = MyLib.Schedule(something)
# Nah, let's unschedule it.
MyLib.Unschedule(identifier)
私は、パターンのこの種の内部コードで大量に使用し、私はいつも識別子として普通の整数を使用します。ユーザーは、基本的にこれを行うだろう。しかし、信頼できないコードによって識別子が使用されている場合、悪意のあるユーザーが単一のUnschedule(randint())
を実行することによってシステム全体を破壊する可能性があります。
実際にスケジュールした識別子のスケジュールを解除できるようにするには、コードのユーザーが必要です。
私が考えることができる唯一の解決策は、識別子として64ビットの乱数を生成し、どちらの識別子が現在配布されているかを追跡して、恐ろしく重複しないようにすることです。または128ビット? 「これは十分にランダムで、重複は起こらない」と言えるのはいつですか?
さらに、これを行うより賢明な方法がありますか?ジェネレータが容易に追跡できる(重複を避ける)識別子トークンを生成する方法はありますか?しかし、受信者に乱数と区別できませんか?
EDIT - 受け入れ答えに基づくソリューション:
from Crypto.Cipher import AES
import struct, os, itertools
class AES_UniqueIdentifier(object):
def __init__(self):
self.salt = os.urandom(8)
self.count = itertools.count(0)
self.cipher = AES.new(os.urandom(16), AES.MODE_ECB)
def Generate(self):
return self.cipher.encrypt(self.salt +
struct.pack("Q", next(self.count)))
def Verify(self, identifier):
"Return true if identifier was generated by this object."
return self.cipher.decrypt(identifier)[0:8] == self.salt
ほとんどの(擬似)乱数ゲラータは、常に同じ種子でジェネレータを初期化することによって、生成されたものを追跡することができます。それは、あなたが同じマシンでそれを使用している場合、正確に同じ番号のシーケンスを生成します。したがって、定数でなければならないシードと生成された識別子の数を計算することにより、以前に生成された数があるかどうかを確認することができます。これは簡単な方法です。識別子をリセットすることができれば(すべてがスケジュールされていなかった場合など)大量の番号を追跡する必要がある場合は非常に遅くなります。 – Trinidad
安全なシステムでUnschedule()を実装するコードはありますか?クライアントが検査できないものは?そうしないと、クライアントが発見できない秘密の値を維持することは期待できません。 –
@GregS:はい、基本的に。クライアントコードはサンドボックス化されています。 @トリニダード:システムは、大きな数の数を処理できる必要があります。少なくとも私は毎秒10000の数字を言うだろう。 (Unscheduleはまれなイベントですが)。 – porgarmingduod