ライセンスキーは、著作権侵害対策としてのデファクトスタンダードです。正直なところ、これは私を「隠すことによるセキュリティ」と見なしますが、ライセンスキーがどのように生成されるかは実際にはわかりません。ライセンスキー生成の良い(安全な)例は何ですか?彼らはどの暗号プリミティブ(もしあれば)を使用していますか?メッセージダイジェストですか?もしそうなら、彼らはどのデータをハッシュしますか?クラッカーが独自のキージェネレーターを構築するのを困難にするために、開発者はどのような方法を採用していますか?キージェネレーターはどのように作られていますか?
11 に答える
昔ながらのCDキーの場合、CDキー(任意の文字列)を生成して検証するのが簡単なアルゴリズムを作成するだけでしたが、有効なCDキーと無効なCDの比率-キーが非常に小さいため、CDキーをランダムに推測しても有効なキーが得られる可能性は低くなります。
それを行うための誤った方法:
StarcraftとHalf-lifeはどちらも同じチェックサムを使用し、13桁目が最初の12桁を検証しました。したがって、最初の12桁は何でも入力でき、13桁目(10の可能性のみ)を推測して悪名高いものになります。1234-56789-1234
検証のアルゴリズムは公開されており、次のようになります。
x = 3;
for(int i = 0; i < 12; i++)
{
x += (2 * x) ^ digit[i];
}
lastDigit = x % 10;
それを行う正しい方法
Windows XPは、かなりの量の情報を取得して暗号化し、文字/数字のエンコードをステッカーに貼り付けます。これにより、MSはキーの確認と製品タイプ(Home、Professionalなど)の取得の両方を同時に行うことができました。さらに、オンラインアクティベーションが必要です。完全なアルゴリズムはかなり複雑ですが、ドイツで発行されたこの(完全に合法な!)論文で
うまく概説されています。
もちろん、あなたが何をしようとも、オンラインサービス(World of Warcraftのような)を提供していない限り、どんな種類のコピー防止もただの屋台です:残念ながら、それが価値のあるゲームであれば、誰かが壊れます(または少なくとも回避します) ) CDキーアルゴリズム、およびその他すべての著作権保護。
それを行うための本当の正しい方法:
オンラインサービスの場合、バイナリファイルを使用する場合でも、それを使用するにはサーバーで認証する必要があるため、作業は少し簡単になります(たとえば、WoWアカウントを持っている)。World of WarcraftのCDキーアルゴリズム(たとえば、プレイタイムカードを購入するときに使用される)は、おそらく次のようになります。
- 非常に大きな暗号的に安全な乱数を生成します。
- データベースに保存し、カードに印刷します。
次に、誰かがプレイタイムカード番号を入力したら、それがデータベースにあるかどうかを確認し、ある場合は、その番号を現在のユーザーに関連付けて、二度と使用できないようにします。
オンラインサービスの場合、上記のスキームを使用しない理由はありません。他のものを使用すると、問題が発生する可能性があります。
私が最初にこの回答を書いたとき、質問はライセンスキーの「オフライン」検証に関するものであるという仮定の下でした。他の回答のほとんどはオンライン検証に対応しており、処理が非常に簡単です(ほとんどのロジックはサーバー側で実行できます)。
オフライン検証で最も難しいのは、膨大な数の一意のライセンスキーを生成し、簡単に侵害されない強力なアルゴリズム(単純なチェックディジットなど)を維持できるようにすることです。
私は数学にあまり精通していませんが、これを行う1つの方法は、グラフをプロットする数学関数を使用することであることに気づきました。
プロットされた線は(十分に細かい周波数を使用する場合)数千の一意のポイントを持つことができるため、そのグラフ上でランダムなポイントを選択し、何らかの方法で値をエンコードすることでキーを生成できます
例として、このグラフをプロットし、4つのポイントを選択して、「0、-500; 100、-300; 200、-100;100,600」として文字列にエンコードします。
既知の固定キー(ひどく弱いですが、目的を果たします)を使用して文字列を暗号化し、結果のバイトをBase32で変換して、最終的なキーを生成します
次に、アプリケーションはこのプロセスを逆にして(base32から実数へ、復号化、ポイントのデコード)、それらの各ポイントがシークレットグラフ上にあることを確認できます。
非常に少量のコードで、膨大な数の一意で有効なキーを生成できます。
ただし、隠すことによるセキュリティは非常に高くなります。コードを分解するのに時間をかける人は誰でも、グラフ化機能と暗号化キーを見つけて、キージェネレーターをモックアップすることができますが、それはおそらくカジュアルな著作権侵害を遅らせるのに非常に役立ちます。
次の要件をカバーする部分キー検証に関する記事を確認してください。
ライセンスキーは、入力するのに十分簡単でなければなりません。
チャージバックやクレジットカードの盗難による購入の場合は、ライセンスキーをブラックリストに登録(取り消す)できる必要があります。
キーをテストするための「電話をかける」必要はありません。この慣習はますます普及しつつありますが、私はまだユーザーとしてそれを高く評価していないので、ユーザーにそれを我慢するように求めません。
クラッカーがリリースされたアプリケーションを分解して、そこから機能する「keygen」を生成することは不可能です。これは、アプリケーションが検証のためにキーを完全にテストしないことを意味します。一部のキーのみがテストされます。さらに、アプリケーションのリリースごとにキーの異なる部分をテストする必要があります。これにより、以前のリリースに基づく偽のキーが、ソフトウェアの新しいリリースで機能しなくなります。
重要:正当なユーザーが誤って無効なキーを入力することはできません。このキーは機能しているように見えますが、誤植が原因で将来のバージョンで失敗します。
私は人々が実際にCDキーを生成するために何をしているのかについての経験はありませんが、(オンラインアクティベーションの道を進みたくないと仮定して)ここにキーを作成するいくつかの方法があります。
数値が(たとえば)17で割り切れる必要があります。多くのキーにアクセスできる場合、推測は簡単ですが、潜在的な文字列の大部分は無効になります。同様に、キーのチェックサムが既知の値と一致する必要があります。
キーの前半が既知の値と連結されている場合、キーの後半までハッシュダウンする必要があります。より良いですが、プログラムには、キーの生成と検証に必要なすべての情報が含まれています。
既知の値+ナンスを(秘密鍵で)暗号化して鍵を生成します。これは、対応する公開鍵を使用して復号化し、既知の値を検証することで検証できます。プログラムには、キーを生成できなくてもキーを検証するのに十分な情報があります。
これらはすべて攻撃に対してオープンです。プログラムはまだ存在しており、チェックをバイパスするようにパッチを適用できます。賢いのは、プログラムに値を格納するのではなく、私の3番目の方法の既知の値を使用してプログラムの一部を暗号化することかもしれません。そうすれば、プログラムを復号化する前にキーのコピーを見つける必要がありますが、復号化された後はコピーされ、1人のユーザーが正当なコピーを取得して、他のすべてのユーザーがソフトウェアにアクセスできるようにすることに対して脆弱です。
CDキーは、ネットワークに接続されていないもののセキュリティではないため、技術的には安全に生成する必要はありません。.netを使用している場合は、ほとんどGuid.NewGuid()を使用できます。
現在の主な用途は、サーバーがCDキーを検証できるマルチプレイヤーコンポーネントです。そのため、「渡されたものをすべて調べて、他の誰かがすでに使用しているかどうかを確認する」ということになるので、どれほど安全に生成されたかは重要ではありません。
そうは言っても、2つの目標を達成するためにアルゴリズムを使用することをお勧めします。
- ある種のチェックサムを持っている。これにより、インストーラーはタイプミスを検出するためだけに「キーが有効ではないようです」というメッセージを表示できます(インストーラーにこのようなチェックを追加すると、ハッカーは必要なすべてのコードを持っているため、キージェネレーターを作成するのは簡単です。チェックし、サーバー側の検証のみに依存すると、そのチェックが無効になります。タイプミスを認識していないためにサーバーがCDキーを受け入れない理由を理解していない合法的な顧客を煩わせるリスクがあります)
- 限られた文字のサブセットを操作します。CDキーを入力して、「これは8またはB?1またはI?QまたはOまたは0?」と推測しようとしています。-明確な文字/数字のサブセットを使用することで、その混乱を解消します。
そうは言っても、海賊が有効なキー(データベースでは有効ですが、店の棚のボックスにあります)を推測し、そのボックスを購入した正当な顧客をめちゃくちゃにすることを避けるために、大規模な配布とある程度のランダム性が必要です。 。
キーシステムには、いくつかのプロパティが必要です。
- 有効なキーはごくわずかです
- ユーザーが持っているすべてのものを与えられたとしても、有効なキーは導出可能であってはなりません。
- あるシステムの有効なキーは、別のシステムの有効なキーではありません。
- その他
これらを提供する必要がある1つの解決策は、公開鍵署名スキームを使用することです。「システムハッシュ」から始めます(たとえば、NICでMacを取得し、並べ替え、CPU-ID情報に加えて、その他の情報をすべて連結して、結果のMD5を取得します(実際にはなりたくない)必要がない場合は、個人を特定できる情報を処理します))CDのシリアル番号を追加し、レジストリキー(またはデータファイル)にblobの有効な署名がない限り、起動を拒否します。ユーザーがブロブをあなたに発送することでプログラムをアクティブにし、あなたが署名を返送します。
潜在的な問題には、実質的に何にでも署名することを提案しているため、誰かが選択された平文および/または選択された暗号文攻撃を実行すると想定する必要があることが含まれます。これは、提供されたシリアル番号を確認し、無効なものからの要求の処理を拒否すること、および特定のs / nからの特定の数を超えるクエリを一定の間隔(たとえば1年に2回)で処理することを拒否することで軽減できます。
いくつか指摘しておきます。まず、熟練した意欲的な攻撃者は、無制限にアクセスできる部分(つまり、CDのすべて)のすべてのセキュリティを回避できます。そのアカウントでできる最善のことは、正当なアクセスを取得するよりも、不正なアクセスを取得することを困難にします。第二に、私は専門家ではないので、この提案されたスキームに重大な欠陥がある可能性があります。
キーの長さに特に関心がない場合、かなり試行錯誤された真の方法は、公開キーと秘密キーの暗号化を使用することです。
基本的に、ある種のナンスと固定署名があります。
例:0001-123456789
ここで、0001はナンス、123456789は固定署名です。
次に、秘密鍵を使用してこれを暗号化し、ABCDEF9876543210のようなCD鍵を取得します。
次に、アプリケーションで公開鍵を配布します。公開鍵を使用して、CD鍵「ABCDEF9876543210」を復号化できます。CD鍵は、の固定署名部分を検証します。
これにより、誰かが秘密鍵を持っていないため、ナンス0002のCD鍵が何であるかを推測することができなくなります。
唯一の大きな欠点は、1024ビットサイズの秘密/公開鍵を使用するとCD鍵がかなり長くなることです。また、些細な量の情報を暗号化しないように、十分な長さのナンスを選択する必要があります。
利点は、この方法が「アクティブ化」なしで機能し、電子メールアドレスやライセンシー名などをナンスとして使用できることです。
この答えはパーティーに約10年遅れていることを私は理解しています。
優れたソフトウェアライセンスキー/シリアル番号ジェネレータは、ランダムな文字の文字列やカーブジェネレータからの値以上のもので構成されています。限定された英数字のアルファベットを使用して、データを短い文字列(XXXX-XXXX-XXXX-XXXXなど)に埋め込むことができます。この文字列には、次のようなあらゆる種類の有用な情報が含まれます。
- 作成日またはライセンスの有効期限が切れる日付
- 製品ID、製品分類、メジャーおよびマイナーバージョン番号
- ハードウェアハッシュのようなカスタムビット
- ユーザーごとのハッシュチェックサムビット(たとえば、ユーザーがライセンスキーとともに電子メールアドレスを入力し、両方の情報がハッシュの計算/検証に使用されます)。
次に、ライセンスキーデータが暗号化され、制限されたアルファベットのアルファベットを使用してエンコードされます。オンライン検証の場合、ライセンスサーバーは情報を復号化するための秘密を保持します。オフライン検証の場合、復号化シークレットは、復号化/検証コードとともにソフトウェア自体に含まれています。明らかに、オフライン検証は、誰かがkeygenを作成することに対してソフトウェアが安全ではないことを意味します。
おそらく、ライセンスキーを作成する上で最も難しいのは、できるだけ多くのデータをできるだけ少ないバイトに詰め込む方法を見つけることです。ユーザーはライセンスキーを手動で入力するため、すべてのビットが重要であり、ユーザーは極端に長く複雑な文字列を入力したくないことを忘れないでください。16〜25文字のライセンスキーが最も一般的であり、配置できるデータ量のバランスを取ります。ソフトウェアのロックを解除するためにキーを入力するためのキーとユーザーの許容範囲を比較します。バイトをビットのチャンクにスライスすると、より多くの情報を含めることができますが、ジェネレーターとバリデーターの両方のコードが複雑になります。
暗号化は複雑なトピックです。一般に、AESのような標準の暗号化アルゴリズムのブロックサイズは、ライセンスキーの長さを短くするという目標と一致しません。したがって、独自のライセンスキーを作成するほとんどの開発者は、独自の暗号化アルゴリズム(頻繁に推奨されないアクティビティ)を作成するか、キーをまったく暗号化しないことになります。これにより、誰かがkeygenを作成することが保証されます。優れた暗号化を正しく行うことは困難であり、Feistelネットワークと既存の暗号がどのように機能するかを十分に理解することが前提条件であると言えば十分です。
キーの確認は、文字列のデコードと復号化、ハッシュ/チェックサムの確認、データ内の製品IDとメジャーおよびマイナーのバージョン番号の確認、ライセンスの有効期限が切れていないことの確認、およびその他の必要なチェックの実行です。実行されます。
keygenを作成することは、ライセンスキーが何で構成されているかを知り、元のキージェネレーターが生成するのと同じ出力を生成することです。ライセンスキー検証のアルゴリズムがソフトウェアに含まれ、ソフトウェアによって使用されている場合、検証プロセスの逆を実行するソフトウェアを作成するだけです。
プロセス全体がどのように見えるかを確認するために、最近書いたブログ投稿で、ライセンスキーの長さ、データレイアウト、暗号化アルゴリズム、および最終的なエンコードスキームの選択について説明します。
https://cubicspot.blogspot.com/2020/03/adventuring-deeply-into-software-serial.html
ブログ投稿からのキージェネレーターとキーベリファイアの実用的な実際の実装は、ここで見ることができます:
https://github.com/cubiclesoft/php-misc/blob/master/support/serial_number.php
上記のクラスのドキュメント:
https://github.com/cubiclesoft/php-misc/blob/master/docs/serial_number.md
上記のシリアル番号コードを使用してライセンスキーを生成および管理する、本番環境に対応したオープンソースライセンスサーバーは、次の場所にあります。
https://github.com/cubiclesoft/php-license-server
上記のライセンスサーバーは、オンラインとオフラインの両方の検証モードをサポートしています。ソフトウェア製品は、オンラインのみの検証からその存在を開始する可能性があります。ソフトウェア製品を廃止する準備が整い、サポートが終了すると、オフライン検証に簡単に移行できます。ユーザーがオフライン検証に切り替えるソフトウェアの最後のバージョンにアップグレードすると、既存のすべてのキーが引き続き機能します。
上記のライセンスサーバーをWebサイトに統合して、ソフトウェアライセンスとインストール可能なデモアプリケーションを販売する方法のライブデモは、ここにあります(Webサイトとデモアプリの両方がオープンソースです)。
https://license-server-demo.cubiclesoft.com/
完全な開示:私はライセンスサーバーとデモサイトソフトウェアの両方の作成者です。
プロセスに複数のステップを組み込んだDRM動作もあります。最もよく知られている例の1つは、CreativeSuiteのインストールを確認するためのAdobeの方法の1つです。ここで説明する従来のCDキー方式が使用され、Adobeのサポートラインが呼び出されます。CDキーはアドビの担当者に渡され、ユーザーが使用するアクティベーション番号が返されます。
ただし、ステップに分割されているにもかかわらず、これは通常のプロセスで使用されるのと同じクラッキング方法の餌食になります。元のCDキーと照合されるアクティベーションキーを作成するために使用されるプロセスがすぐに発見され、両方のキーを組み込んだジェネレーターが作成されました。
ただし、この方法は、インターネットに接続していないユーザーが製品を確認する方法として引き続き存在します。今後、インターネットアクセスが普及するにつれて、これらの方法がどのように排除されるかは容易に理解できます。
すべてのCDは、著作権侵害に対する保護をまったく提供せずに、正直なユーザーに不便をかけるだけのコピー防止アルゴリズムです。
「海賊」は、1枚の正規のCDとそのアクセスコードにアクセスするだけでよく、n個のコピーを作成して配布できます。
コードを暗号的に安全にするかどうかは関係ありません。プレーンテキストでCDを提供する必要があります。そうしないと、正当なユーザーがソフトウェアをアクティブ化できません。
最も安全なスキームでは、ユーザーがソフトウェアを実行するマシンの詳細(CPUシリアル番号、MACアドレス、IPアドレスなど)をソフトウェアサプライヤに提供するか、サプライヤのWebサイトにソフトウェアを登録するためにオンラインアクセスが必要です。その見返りに、アクティベーショントークンを受け取ります。最初のオプションは多くの手動管理を必要とし、非常に価値の高いソフトウェアにのみ価値があります。2番目のオプションはスプーフィングされる可能性があり、ネットワークアクセスが制限されている場合やファイアウォールの背後で立ち往生している場合は絶対に腹立たしいです。
全体として、顧客との信頼関係を確立するのははるかに簡単です!
セキュアライセンスAPIは、それを使用してソフトウェアプロジェクトで非常に簡単に使用および実装できます(セキュアライセンスを作成するには、 https://www.systemsoulsoftwares.com/からデスクトップアプリケーションをダウンロードする必要があります) 。
- システムハードウェア(CPU、マザーボード、ハードドライブ)に基づいてクライアントソフトウェアの一意のUIDを作成します(UIDはその一意のシステムの秘密鍵として機能します)
- 暗号化されたライセンス文字列をクライアントシステムに非常に簡単に送信できます。ライセンス文字列を検証し、その特定のシステムでのみ機能します
- この方法により、ソフトウェア開発者または会社は、ソフトウェア/開発者/ディストリビューターサービス/機能/クライアントに関する詳細情報を保存できます。
- クライアントソフトウェア機能のロックとロック解除を制御できるため、機能を変更して同じソフトウェアのバージョンを増やすための開発者の時間を節約できます。
- 何日でも試用版も気になります
- 登録時にオンラインでDateTimeを確認することにより、ライセンスのタイムラインを保護します
- 開発者にすべてのハードウェア情報のロックを解除します
- 開発者がより複雑で安全なコードを作成するためのライセンスのすべてのプロセスでアクセスできるすべてのビルド前およびカスタム機能を備えています