有三种基本的处理方法。你如何做到这一点取决于你生成了多少密钥,以及能够在以后使密钥失效的重要性。你选择哪一个取决于你。
选项 1:服务器数据库存储
当服务器生成密钥(例如使用您的算法)时,您将其存储在数据库中。然后,您需要做的就是检查密钥是否在数据库中。
请注意,您的算法需要的熵比您提供的要多得多。当前时间戳是不够的。相反,使用强随机性:
$key = mcrypt_create_iv($length_needed, MCRYPT_DEV_URANDOM);
或者,如果您没有 mcrypt:
$key = openssl_random_pseudo_bytes($length_needed);
或者,如果您没有 mcrypt 和 openssl,请使用库
请注意,它md5
返回一个十六进制输出 (a-f0-9),其中所有以上都返回完整的随机二进制字符串(字符 0 - 255)。所以要么base64_encode()
它,要么bin2hex()
它。
优点:
- 易于实施
- 可以在以后“停用”已发布的密钥
- 无法伪造新密钥
缺点:
- 每个键都需要持久存储
- 可能无法很好地扩展
- 需要“密钥服务器”来验证密钥
选项 2:签名密钥
基本上,您生成一个强随机密钥(从这里称为私钥),并将其存储在您的服务器上。然后,在生成许可证密钥时,您会生成一个随机 blob,然后 HMAC 用私钥对其进行签名,并使许可证成为该块的一部分。这样,您就不需要存储每个单独的密钥。
function create_key($private_key) {
$rand = mcrypt_create_iv(10, MCRYPT_DEV_URANDOM);
$signature = substr(hash_hmac('sha256', $rand, $private_key, true), 0, 10);
$license = base64_encode($rand . $signature);
return $license;
}
function check_key($license, $private_key) {
$tmp = base64_decode($license);
$rand = substr($tmp, 0, 10);
$signature = substr($tmp, 10);
$test = substr(hash_hmac('sha256', $rand, $private_key, true), 0, 10);
return $test === $signature;
}
优点:
缺点:
- 无法单独“停用”密钥
- 需要存储“私钥”
- 需要“密钥服务器”来验证密钥。
选项 3:公钥加密
基本上,您生成一个公钥/私钥对。您将公钥嵌入到您的应用程序中。然后,您生成一个密钥(类似于上面的“签名密钥”),但不是使用 HMAC 签名对其进行签名,而是使用私钥对其进行签名。
这样,应用程序(具有公钥)可以直接验证签名,而无需回调您的服务器。
function create_key($private_key) {
$rand = mcrypt_create_iv(10, MCRYPT_DEV_URANDOM);
$pkeyid = openssl_get_privatekey($private_key);
openssl_sign($rand, $signature, $pkeyid);
openssl_free_key($pkeyid);
$license = base64_encode($rand . $signature);
return $license;
}
function check_key($license, $public_key) {
$tmp = base64_decode($license);
$rand = substr($tmp, 0, 10);
$signature = substr($tmp, 10);
$pubkeyid = openssl_get_publickey($public_key);
$ok = openssl_verify($rand, $signature, $pubkeyid);
openssl_free_key($pubkeyid);
return $ok === 1;
}
优点:
- 易于实施
- 不需要持久存储
- 微不足道的规模
- 不需要“密钥服务器”来验证密钥
缺点: