端到端加密技术详解与实战经验分享

长孙晓莉 安全 阅读 782
赞 35 收藏
二维码
手机扫码查看
反馈

又踩坑了,端到端加密搞不定

最近在做一个项目,需要实现端到端加密。一开始以为挺简单的,结果折腾了半天发现,这里面的坑可真不少。

端到端加密技术详解与实战经验分享

问题来了:密钥交换失败

最开始的问题是密钥交换失败。我用的是Web Cryptography API,本来以为按文档一步步来就能搞定,结果报错说密钥交换失败。我检查了好几遍代码,没发现什么问题,搞得我一头雾水。

排查过程:各种尝试

先从密钥生成开始查起,我的代码如下:

const keyPair = await crypto.subtle.generateKey(
  {
    name: "ECDH",
    namedCurve: "P-256"
  },
  true,
  ["deriveBits", "deriveKey"]
);

然后是密钥导出和导入,这部分代码也很简单:

const publicKey = await crypto.subtle.exportKey("spki", keyPair.publicKey);
const importedPublicKey = await crypto.subtle.importKey(
  "spki",
  publicKey,
  { name: "ECDH", namedCurve: "P-256" },
  true,
  []
);

这里我踩了个坑,就是密钥格式的选择。我一开始用了JWK格式,后来试了下发现SPKI格式更合适。改完后还是不行,我又去查了查文档,发现可能是密钥参数的问题。

核心代码就这几行

最后终于找到了问题所在,原来是密钥参数设置不对。正确的代码应该是这样的:

const keyPair = await crypto.subtle.generateKey(
  {
    name: "ECDH",
    namedCurve: "P-256"
  },
  true,
  ["deriveBits", "deriveKey"]
);

const publicKey = await crypto.subtle.exportKey("spki", keyPair.publicKey);
const importedPublicKey = await crypto.subtle.importKey(
  "spki",
  publicKey,
  { name: "ECDH", namedCurve: "P-256" },
  true,
  []
);

const sharedSecret = await crypto.subtle.deriveBits(
  { name: "ECDH", public: importedPublicKey },
  keyPair.privateKey,
  256
);

关键在于deriveBits方法的参数设置,特别是public字段要指向导入的公钥。这样密钥交换才能成功。

技术细节:为什么要这么写

其实这里涉及到一些密码学的基础知识。ECDH(椭圆曲线Diffie-Hellman)是一种密钥交换算法,它允许两个用户在不安全的通信信道上协商一个共享密钥。整个过程分为几个步骤:

  • 生成密钥对:每个用户生成一个私钥和对应的公钥。
  • 交换公钥:用户将自己的公钥发送给对方。
  • 计算共享密钥:每个用户使用自己的私钥和对方的公钥来计算共享密钥。

在这个过程中,密钥的格式和参数设置非常重要。SPKI格式适用于公钥的导出和导入,而JWK格式更适合JSON环境下的密钥表示。选择合适的格式可以避免很多不必要的麻烦。

还有点小问题,但无大碍

改完后还有一些小问题,比如有时候密钥交换会慢一些,但这不影响整体功能。如果有人有更好的方案,欢迎在评论区交流。

以上是我踩坑后的总结,希望对你有帮助。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论