使用Python生成与Java兼容的DiffieHellman

2024-09-30 10:33:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用Python重写以下代码。原始代码是使用sjcl库用Javascript编写的

// Inputs
var serverPubX = "WIUBDotrk02Rk/apL11jQPbmX0quyaYz2EIkGUlVf7s=";
var serverPubY = "diZ2CbfSUy5Kr82OIfd4Ajusq2K+/kjGZ7ymcqVwn2k=";

// The code
var serverPubXBits = sjcl.codec.base64.toBits(serverPubX);
var serverPubYBits = sjcl.codec.base64.toBits(serverPubY);
var serverPubKeyPointBits = serverPubXBits.concat(serverPubYBits);

var serverPubKey = new sjcl.ecc.elGamal.publicKey(
    sjcl.ecc.curves.c256, serverPubKeyPointBits);

var clientKeys = sjcl.ecc.elGamal.generateKeys(256, 1);

// What I need:
var sharedKey = clientKeys.sec.dhJavaEc(serverPubKey);

我的主要问题是dhJavaEc函数。根据sjcl文档,它是一个Java compatible Diffie-Hellmann function。但我在pycryptodome库中找不到任何等价的东西

我检查了dhJavaEc代码它就是这样做的:

// Looks like it converts the server key to Jacobian and then multiply it by client key
serverPubKey.J.toJac().mult(clientKeys.sec.I, serverPubKey.J).toAffine().x.toBits()

// serverPubKey.J is the X and Y keys concatenated:
sjcl.codec.base64.fromBits(serverPubKey.J.toBits())
"WIUBDotrk02Rk/apL11jQPbmX0quyaYz2EIkGUlVf7t2JnYJt9JTLkqvzY4h93gCO6yrYr7+SMZnvKZypXCfaQ=="

// In my example, clientKeys.sec.I is this:
sjcl.codec.base64.fromBits(clientKeys.sec.I.toBits())
"zIhDVlFUpWQiRP+bjyEIhSLq8rcB8+XInXGhm6JGcVI="

// And the calculated key is:
sjcl.codec.base64.fromBits(sharedKey)
"ZBin/RV1qnfKoIuel+5fzv1y8rn3UZkMPO3pXva3VzQ="

如何使用Python生成“sharedKey”等价物


Tags: thekey代码isvarseccodecbase64
1条回答
网友
1楼 · 发布于 2024-09-30 10:33:21

PyCryptodome目前似乎不支持ECDH,请参见Future plans。另一种选择是加密库,请参见Elliptic Curve Key Exchange algorithm

库要求私钥为int,而未压缩格式的公钥为bytes-object。未压缩格式由连接的x和y坐标组成,前面有一个0x04字节

^{}定义了secp256r1(akaprime256v1akaNIST p-256

那么在Python中使用加密的一个可能实现是:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
import base64

curve = ec.SECP256R1()

clientKey = 'zIhDVlFUpWQiRP+bjyEIhSLq8rcB8+XInXGhm6JGcVI='
privateKeyInt = int.from_bytes(base64.b64decode(clientKey), byteorder='big', signed=False)
privateKey = ec.derive_private_key(privateKeyInt, curve, default_backend())

serverPubKey = 'WIUBDotrk02Rk/apL11jQPbmX0quyaYz2EIkGUlVf7t2JnYJt9JTLkqvzY4h93gCO6yrYr7+SMZnvKZypXCfaQ=='
publicKeyUncomp = b'\x04' + base64.b64decode(serverPubKey)
publicKey = ec.EllipticCurvePublicKey.from_encoded_point(curve, publicKeyUncomp)

sharedSecret = privateKey.exchange(ec.ECDH(), publicKey)
print(base64.b64encode(sharedSecret).decode('utf8')) # ZBin/RV1qnfKoIuel+5fzv1y8rn3UZkMPO3pXva3VzQ= 

它生成与JavaScript代码相同的共享机密

相关问题 更多 >

    热门问题