所以现在有很多不同的服务,Google APIs, Twitter APIs, Facebook APIs, etc.
每个服务都有一个 API 密钥,例如:
AIzaSyClzfrOzB818x55FASHvX4JuGQciR9lv7q
所有密钥的长度和它们包含的字符都不同,我想知道生成 API 密钥的最佳方法是什么?
我不是在要求一种特定的语言,只是创建密钥的一般方法,它们应该是用户应用程序详细信息的加密,还是哈希,或随机字符串的哈希等。我们应该担心哈希吗算法(MSD、SHA1、bcrypt)等?
编辑: 我和几个朋友(电子邮件/推特)谈过,他们建议只使用去掉破折号的 GUID。
这对我来说似乎有点老套,希望能得到更多的想法。
使用专为密码学设计的随机数生成器。然后 base-64 编码数字。
这是一个 C# 示例:
var key = new byte[32];
using (var generator = RandomNumberGenerator.Create())
generator.GetBytes(key);
string apiKey = Convert.ToBase64String(key);
API 密钥需要具有以下属性:
通常您将拥有数千或数百万个 API 密钥,而不是数十亿个,因此他们不需要:
因此,生成 API 密钥的一种方法是获取两条信息:
并使用私人秘密签名。
柜台保证他们唯一识别用户,签名防止伪造。可撤销性要求在执行任何需要 API 密钥授权的操作之前检查密钥在数据库中是否仍然有效。
如果您需要从多个数据中心生成密钥,或者没有其他好的分布式方式来分配序列号,那么一个好的 GUID 生成器是递增计数器的一个很好的近似值。
或随机字符串的散列
散列并不能防止伪造。 Signing 保证密钥来自您。
更新,在Chrome的控制台和Node.js中,你可以发出:
crypto.randomUUID()
示例输出:
'4f9d5fe0-a964-4f11-af99-6c40de98af77'
原答案(更强):
您可以通过打开一个新选项卡,在 Chrome 上按 CTRL + SHIFT + i,然后输入以下立即调用的函数表达式 (IIFE) 来尝试您的 Web 浏览器控制台:
(async function (){
let k = await window.crypto.subtle.generateKey(
{name: "AES-GCM", length: 256}, true, ["encrypt", "decrypt"]);
const jwk = await crypto.subtle.exportKey("jwk", k)
console.log(jwk.k)
})()
示例输出:
gv4Gp1OeZhF5eBNU7vDjDL-yqZ6vrCfdCzF7HGVMiCs
参考资料:
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey
https://developer.mozilla.org/zh-CN/docs/Web/API/SubtleCrypto/exportKey
我会承认我主要是为了自己写这篇文章以供将来参考...
我使用 UUID,格式为小写,没有破折号。
生成很容易,因为大多数语言都内置了它。
API 密钥可能被泄露,在这种情况下,用户可能希望取消他们的 API 密钥并生成一个新密钥,因此您的密钥生成方法必须能够满足此要求。
如果你想要一个只有字母数字字符的 API 密钥,你可以使用 base64-random 方法的变体,只使用 base-62 编码。 base-62编码器基于this.
public static string CreateApiKey()
{
var bytes = new byte[256 / 8];
using (var random = RandomNumberGenerator.Create())
random.GetBytes(bytes);
return ToBase62String(bytes);
}
static string ToBase62String(byte[] toConvert)
{
const string alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
BigInteger dividend = new BigInteger(toConvert);
var builder = new StringBuilder();
while (dividend != 0) {
dividend = BigInteger.DivRem(dividend, alphabet.Length, out BigInteger remainder);
builder.Insert(0, alphabet[Math.Abs(((int)remainder))]);
}
return builder.ToString();
}
API 密钥应该是一些随机值。随机到无法预测。它不应包含它所针对的用户或帐户的任何详细信息。如果您确定创建的 ID 是随机的,那么使用 UUID 是个好主意。
Windows 的早期版本产生了可预测的 GUID,例如,但这是一个古老的故事。
在终端中,您可以像这样使用
openssl
:
openssl rand -hex 32
示例输出:
1e846f3fcf103f64ca10fa4eac73bfae32ef10750bf4eae29132dc099526c561
我喜欢 Chris Chiasson 在浏览器中
crypto.subtle
的使用,但想要一个命令行版本。如果你安装了 NodeJS,这可以保存在一个文件中(例如,mkapikey.js
):
#!/usr/bin/env node
crypto.subtle.generateKey({name:"AES-GCM", length:256},true,
["encrypt","decrypt"]).then(key => {crypto.subtle.exportKey("jwk",key).
then(jwk => {console.log(jwk.k)})});
chmod +x
到可执行文件或使用 node mkapikey.js
调用。
chmod +x mkapikey.js
./mkapikey.js
4SvnAK87DD0t3WMS878UCY-obmADtPeBn6X4gFOtUig