首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >服务是如何生成和使用公共和秘密API密钥的?

服务是如何生成和使用公共和秘密API密钥的?
EN

Stack Overflow用户
提问于 2019-03-05 18:43:11
回答 2查看 5.5K关注 0票数 12

Google、Stripe和其他许多公司都有公开的API密钥和秘密API密钥。

生成随机字符串很容易,但我的问题是,如何生成公共密钥和秘密密钥,存储它们并正确使用它们?

公共API的关键是告诉用户是谁,而秘密是确认用户的身份。

我的流程如下:-用户创建帐户用户激活服务(内部)服务返回公共和秘密API密钥(UARRHAtPtJcLxx5RmMWo9oTrca4gRt2k,C9YS7Mhzichq2vqBuRkNJxkNci5W2Xua)用户在他/她的网站上使用公钥,在服务器端使用私钥。

当用户请求API密钥时,我使用nodejs并根据需要生成公钥:

代码语言:javascript
复制
let public = await crypto.randomBytes(32).toString('base64');

将秘密存储在数据库中就像将密码存储在明文中一样。我想我们不想这样,它需要被打散。例如,我是否生成“私有”密钥并使用argon2对其进行散列?用户将永远无法再次看到他/她的密钥,并需要立即保存它,这是一个很好的实践吗?

我找不到多少关于这应该如何工作的信息。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-07 09:58:20

从技术上讲,你所指的只是一个用户名和一个密码。唯一重要的区别是它们通常是由API和非常随机生成的,而不是由用户选择的真实用户名和密码,并且通常不是很随机。(对这些公钥和私钥的调用有点误导,因为公钥加密是不同的--对于API密钥来说,通常不需要这样做,管理PKI是一种蠕虫,而且正确地管理PKI也非常昂贵。)

由于它们在技术上与用户名和密码相同,所以您需要对它们进行类似的处理。让我们调用这些客户机id (“公共”部分)和客户端密钥(“秘密”部分)。

几点想法:

  • 您应该使用加密安全的随机生成器来生成随机字符串。上面提到的crypto.randomBytes()是可以的。
  • 您应该考虑熵来为键设置适当的长度。熵基本上是键的“随机性”,是以位来衡量的。举个例子,如果密钥空间是1024个不同的可能键,概率相等,那么你可以说密钥有log2(1024) = 10位熵。熵将密钥的长度与随机源的安全性解耦,例如,您可以有非常长的密钥,但这些密钥仍然不安全,因为随机源存在缺陷。您想要的密钥熵大小取决于usecase,就像在任何情况下都有可能发生离线攻击或仅在在线请求等情况下(您也应该考虑离线攻击,因为离线攻击非常快)。作为经验法则,您不应该低于128位熵,为了更高的安全性,您可能应该使用256+位。如果键是区分大小写和字母数字的,那么就有62个不同的可能字符,密钥长度为22提供~131位(log2(62^22) =~ 130.99)。当然,你总是可以走得更长,对于256位,你需要43的长度和区分大小写的字母数字。
  • 正如您正确地指出的,存储这样的键是非常关键的。至少,您希望存储散列(使用适当的散列,参见下面),就像任何其他密码一样,这样即使攻击者访问了您的数据库,他们也不会看到您的api密钥。任何合适的密钥派生函数(Argon2、bcrypt、PBKDF2等)都适合用于此目的,而普通密码散列函数(sha1、sha2等)则不适用。
  • 您是对的,如果您散列这些秘密,用户将只能在生成它们时才能看到它们,并且永远不会再次看到它们。这正是在安全的在线服务中发生的事情,而且通常是一个很好的实践。您可以警告您的用户注意这个秘密,因为您将无法再次向他们展示。(而且,如果他们忘记了,他们可以理想地生成一个新的,所以这通常不是什么大事。)
  • 更好的办法是把这些钥匙藏在别的地方。考虑到云,这些秘密的一个好地方将是您的云提供商提供的服务,例如AWS中的秘密管理器( secrets )。其好处包括使用KMS密钥进行加密、审核,并且您可以确保访问密钥的唯一方法是通过适当的IAM角色(例如,您不需要担心公开备份之类的事情)。
  • 虽然客户端id不是秘密,但您需要在存储中保护它的完整性(以及与客户端秘密关联的完整性)。设想一个场景,攻击者可以以某种方式更改数据库,并将另一个(攻击者已知的)客户端秘密分配给现有的客户端id。这将意味着与该客户端id相关的数据完全受损。因此,您希望确保除了保持clietn的安全之外,攻击者也不可能更改这些信息(例如,通过对所涉及的组件的访问控制)。
票数 14
EN

Stack Overflow用户

发布于 2020-04-19 08:20:03

我认为我们可以生成一对公钥和密钥(私钥),使用下面的code..you可以引用链接以在此处生成密钥对( doc )。链接

代码语言:javascript
复制
var pk="";
var sk="";
var string= payload;
const { generateKeyPair } = require('crypto');
generateKeyPair('rsa', {
      modulusLength: 4096,
      publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
      },
      privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: 'top secret'
      }
    }, (err, publicKey, privateKey) => {
      try {
          pk=publicKey;
          sk=privateKey;

      } catch (error) {
          console.log(err)

      }
    });

现在我们有了秘密密钥和公共key....so,我们可以实现HMAC authentication...ref..请使用hmac身份验证文档

代码语言:javascript
复制
var hmac = crypto.createHmac('sha384', sk).update(string).digest('hex');

request.post({uri:..., json: { hmac, pk, string }, function(err, response, body) {
   console.log(body);
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55009503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档