4

私がプログラムを書いて、それを人々に配布したいとしましょう。ソフトウェアのライセンス コピーを持っていることを確認するために、インストール中にユーザーにシリアル番号を要求できるようにしたいと考えています。さらに、アクセスできるソフトウェアのエディションと、ライセンスの有効期限をシリアル番号に保存したいと考えています。

これを達成するために考えられる概念的な方法が少なくとも 2 つあります。

  1. ユーザーがソフトウェアを購入するサーバーでシリアル番号を生成し、電子メールで送信します。ソフトウェアは、インストール中にサーバーに接続し、製品をアクティブ化します。サーバーは、ライセンス権限と有効期限を返します。シリアルには特定の形式や数学的規則はなく、サーバー上のデータベースに対して単純にチェックされます。

  2. 顧客用のシリアルを生成し、電子メールで送信します。シリアルには、有効かどうか、どのライセンスに対応するか、有効期限がいつ切れるかをプログラムがチェックできる特別な数学的プロパティがあります。

私は主に2番目の方法に興味があります。この情報をシリアル番号にエンコードする際に使用される技術は何ですか? 簡単な概要を説明できれば、それは素晴らしいことです。そうでなければ、これについて議論している良い本やウェブサイトをいくつかお勧めできますか?

何年にもわたってコーディングを行ってきましたが、これらの手法の実装や説明を実際に見たことがないのは不思議です。

4

2 に答える 2

3

あなたが考えていることは、基本的に独自のライセンス モジュールを作成することです。それは何も悪いことではなく、あなたが自分自身をロールバックする場合、それは無料になります (コードを書いてデバッグする時間だけです)。ただし、クラックするのは非常に簡単なので、ある種のライセンス準拠 (コピー防止など) を取得するためにこれを行う場合は、気にしません。

なんらかの方法で物理マシンにバインドしますか? 1 つの方法は、CPU シリアル番号、HD シリアル番号、MAC アドレスなど、または上記の組み合わせを取得し、それらをハッシュして、ハッシュを使用して起動時にチェックし、ライセンスが有効であることを確認することです。もちろん、ユーザーが何かを変更すると、チェックが失敗し、有効なライセンスを持っていても、ソフトウェアが実行されなくなることに苛立つ可能性があります。

違法なコピーや使用から保護するためにこれを行っている場合、提案しているスキーマは通常、非常に簡単にクラックできます。クラッカーは、適切なライセンスをチェックする場所を探し、asm コードにパッチを適用してその周りに分岐するか、常に正を返します。アプリが .NET の場合、ソース コードに逆戻りして、ライセンス チェック部分を削除できます。

免責事項: 私はライセンス管理/コピー防止ツール会社 ([Wibu-Systems]) 1で働いており、これだけを行っているため、ほとんどのシステムを簡単に打ち負かすことができることを知っています。

次の 3 つの方法のいずれかをお勧めします。

  1. アプリを無防備のままにして、海賊版コピーに対する売り上げの比率が妥当であることを願っています。
  2. 単純なシステムを展開しますが、ソフトウェアに価値がある場合、誰かがすばやく簡単にクラックすることを認識してください。これを半分でも適切に行うには、複雑なコーディングとメンテナンスの準備をしてください。
  3. CodeMeterHASP、またはKeyLokなどの商用品質の保護システムを購入します。他のものよりも優れているものもありますが (もちろん、私たちのものが最高だと考えています)、無料のものはありません。
于 2011-04-28T22:15:02.767 に答える
1

さて、答えなしで2週間。基本的な方法を使用して、比較的安全で拡張性の高いシリアル番号を生成するために思いついた非常に簡単な方法で答えます。

数学者として、私はあらゆる種類の情報をシリアル番号に保存するためのいくつかの高度な技術があることを非常に確信していますが、私は主に手っ取り早い方法に興味があります。

考慮すべき、素朴で非数学的な力ずくのテクニックを次に示します。

byte[]使用する文字を含む配列を作成します。ヘクスのみを使用できますが、自分を制限する理由はありません。英数字の範囲全体から「0」/「O」および「1」/「I」を引いたものを使用しないのはなぜですか(明らかな理由で)。

次に、次のように関数を記述します(例はC#です)。

byte[] genRandomSerial(int length, byte[] characters, Random r)
{
  var sn = new byte[length];

  for (int i = 0; i < length; i++)
    sn[i] = characters[r.Next(0, characters.Length)];

  return sn;
}

これにより、ランダムなシリアル番号が提供されますが、有効かどうかはわかりません。

次:

int sum(byte[] sn, MD5 md5)
{
  val = 0;

  foreach (byte b in md5.ComputeHash(sn))
    val += (int)b;

  return val;
}

その後

bool validate(byte[] sn, uint radix, uint expected, MD5 md5)
{
  return (sum(sn, md5) % radix == expected);
}

現在、MD5ハッシュ関数の16バイトの出力を合計し、 nを法とする合計がxに等しいかどうかを評価する方法があります。

次に、存在するシリアル番号の数を決定します。シリアル番号が多いほど、誰かが有効な組み合わせをランダムに推測しやすくなります。

ランダムシリアルをブロックに分割します。4の5ブロックを考えてみましょう:ABCD-EFGH-IJKL-MNOP-QRSTの形式で20文字を与えます

シリアル番号から5つのアレイを作成します。

{A、B、C、D}、{E、F、G、H}、{I、J、K、L}、{M、N、O、P}、および{Q、R、S、T} 。

5つのアレイが次のように検証されるかどうかをテストします。

if (validate(block1, radix, expected, md5))
  // This block is valid.

基数を2に設定すると、ブロックが有効になる確率は1/2になります。基数を10に設定すると、ブロックが有効になる確率は1/10になります。5つのブロックがあり、それぞれの基数を10に設定した場合、シリアル番号全体が有効になる確率は0.1 ^ 5=0.00001です。(つまり、100000のランダムシリアルごとに1つが有効になります。つまり、英数字の範囲から「0」/「O」、「1」/「I」を引いたものを使用すると、(8 + 24)^ nになります。 * 0.00001 =〜1.2*シリアル長20の場合は10^19の有効なキー。これは多くのことですが、とにかくすべてを見つけることはできないことを忘れないでください。基数が高いほど、シリアルの安全性は高くなりますが、生成に時間がかかります)。

'expected'は0と基数-1の間のどこかにある必要があることに注意してください

これで、特定のシリアル番号を有効として検証する方法ができましたが、それがどのタイプのシリアルであるかをどのように保存するのでしょうか。実際のところ、私たちはすでにそれを行う方法を持っています。ランダムな(ただし検証済みの)シリアル'sn'全体を取得します。

int licenseType = sum(sn, md5) % 4; // Where 4 is the number of licenses you want to have

if (licenseType == 0)
{
  // Evaluation
}
else if (licenseType == 1)
{
  // Standard
}
else if (licenseType == 2)
{
  // Full
}
else // licenseType == 3
{
  // Unrestricted
}

キーを生成するにつれて、各タイプのライセンスの数は徐々に横ばいになります。

有効期限などの追加情報をキーに保存する場合は、同様の方法を使用できます。たとえば、12を法とする奇数文字の合計を取得して有効期限の月を取得し、偶数文字の合計の31を法として有効期限を取得することができます。

適用するこれらの制限と細分化が多いほど、各タイプのキーの生成にかかる時間が長くなります。

于 2011-04-18T05:48:28.153 に答える