比較的強固なライセンスキーの生成

プログラムのバイナリ自体が改ざんされる可能性を無視して、解析・偽装が困難なライセンスキーを生成/検証する手法というと、やっぱり以下のような公開鍵暗号方式になるんだろうか。

  • RSAのキーペアを作成しておく。
  • 管理者側は「プログラム固有の情報+ユーザ固有の情報」を秘密鍵で暗号化してライセンスキーとする。
  • 1024ビットの鍵の場合、パディングの88ビットを引いて936ビット=117バイトを固有情報の記述に使用可能。ユーザ名とメールアドレス程度の情報は格納することができる。
  • この場合、ライセンスキーの長さも1024ビットになる。これをBase64エンコードすれば172文字のキーになる。Base16なら256文字。
  • プログラム側には公開鍵を埋め込んでおく。
  • ユーザが入力したライセンスキーを公開鍵で復号化して検証する。

以下はライセンスキー生成部のサンプル。

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.RSAPrivateKeySpec;

import javax.crypto.Cipher;

public class LicenseKeyGenerator {
    // 実際の使用時は適切な値をセットする
    private static final String MODULUS = "XXXXXXXXXX";
    private static final String PRIVATE_EXPONENT = "XXXXXXXXXX";

    public byte[] generateLicenseKey(byte[] source) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, createPrivateKey());
        return cipher.doFinal(source);
    }

    private PrivateKey createPrivateKey() throws Exception {
        RSAPrivateKeySpec spec = new RSAPrivateKeySpec(
                new BigInteger(MODULUS), new BigInteger(PRIVATE_EXPONENT));
        KeyFactory factory = KeyFactory.getInstance("RSA");
        return factory.generatePrivate(spec);
    }
}

この方法ではライセンスキーがかなり長い文字列になるので、メールに添付されたライセンスキーを入力画面にコピペしてもらうような使い方になると思う。もっと短いキーの生成手法はあるのかな?

追記

電子署名方式にすれば、キーがもっと長くなってしまうけど、任意長のライセンス情報を入れられますね。