0

我正在寻找一个 dart 包,以便在 Flutter 应用程序中实现密钥交换协议(椭圆曲线 Diffie-Hellman)。

  • 应用程序在登录期间生成一个密钥对并将公钥发送到服务器(因此每次登录都会生成一个新的密钥对)
  • 服务器发回它刚刚生成的公钥
  • 应用程序从它的私钥和服务器的公钥生成一个密钥
  • app 包含所有后续发送到服务器的消息的 hmac

我查看了支持 Diffie-Hellman 的 pointycastle。但我找不到任何生成密钥的方法。这就是 java 生成的内容:

 KeyAgreement a = KeyAgreement.getInstance("ECDH", "SC");
 a.init(mProvisionerPrivaetKey);
 a.doPhase(publicKey, true);

想知道您是否发现了一些线索,可以从 dart 中的私钥和服务器的公钥生成密钥。

4

1 回答 1

0

这是如何使用本地 EC 密钥对和服务器的公共点生成与 Java 兼容的共享密钥pointycastle。(请注意,JavaKeyAgreement仅使用x点的坐标 -y未使用。我不熟悉提供SC程序,它可能会做不同的事情。)

Uint8List sharedSecret(AsymmetricKeyPair localPair, ECPoint remotePublicPoint) {
  var ss = remotePublicPoint * (localPair.privateKey as ECPrivateKey).d;
  return hex.decode(toHex(ss.x.toBigInteger()));
}

toHex是一个实用程序,它打印一个BigInt到十六进制,确保有偶数个十六进制数字。

String toHex(BigInt bi) {
  var hex = bi.toRadixString(16);
  return (hex.length & 1 == 0) ? hex : '0$hex';
}

hex.decode来自package:convert(注意 - 不是dart:convert)所以一定要添加pubspec.yaml并导入它:import 'package:convert/convert.dart';

最后,要以十六进制格式解析服务器的公共点,请aaaaaa,bbbbbb使用:

ECPoint parsePoint(String s) {
  var parts = s.split(',');
  return domainParams.curve.createPoint(
    BigInt.parse(parts[0], radix: 16),
    BigInt.parse(parts[1], radix: 16),
  );
}

你的曲线在哪里domainParams,例如:

var domainParams = ECCurve_secp256k1();
于 2019-10-11T18:54:53.327 回答