如果对等公用密钥未编码为主机专用密钥,如何生成DH共享密钥?

时间:2020-10-19 10:19:10

标签: python cryptography elliptic-curve diffie-hellman

我正在尝试在主机(python)和设备(使用C)之间执行DH密钥交换。 我当前在主机上使用cryptography.io's elliptic curve exchange algorithm

这种情况: 我已经收到对等方的公钥,它是64个整数的列表,它是原始的,没有填充,没有包装,没有引号。

但是,当我必须生成共享密钥时,该示例显示如下:

shared_key = private_key.exchange(ec.ECDH(), peer_public_key)

但是抛出错误,ofc:

AttributeError 'list' object has no attribute 'curve'

这应该是因为我的私钥是_EllipticCurvePrivateKey对象,而对等公钥只是一个列表。

如何将对等公共密钥转换为合适的公共密钥以生成共享密钥?

1 个答案:

答案 0 :(得分:1)

密码学支持使用公钥的ec.EllipticCurvePublicKey.from_encoded_point()(自版本2.5)和私钥的ec.derive_private_key()(自版本1.6)导入 raw EC密钥。

示例(对于椭圆曲线secp256k1):

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

curve = ec.SECP256K1()

# Key A: Generate a new key pair
private_keyA = ec.generate_private_key(curve)
public_keyA = private_keyA.public_key()

#Key B: Derive key pair from raw data
private_valueB = 0x36A4B92DCD0077CDA3173D218733931497582B733285B8961CAD616E927691B9
public_valueB = bytes.fromhex('04D4465B9B77F9811BF89B20064A5214C00210D6183910BDC220BA65F8B9D327933C1D7FD3B7DB0A69420A614C9D9303D09BA96C83203927B149A6E28D01E0C253')
private_keyB = ec.derive_private_key(private_valueB, curve, default_backend())
public_keyB = ec.EllipticCurvePublicKey.from_encoded_point(curve, public_valueB)

# Shared Keys
shared_keyA = private_keyA.exchange(ec.ECDH(), public_keyB)
print(shared_keyA.hex())

shared_keyB = private_keyB.exchange(ec.ECDH(), public_keyA)
print(shared_keyB.hex())

在发布的代码中,密钥对A是新生成的,而密钥对B是从原始数据生成的。在执行代码时,这些密钥会按预期在两侧生成相同的秘密。

请注意有关公钥的信息,表示公钥的点可以采用压缩(仅x坐标)或未压缩格式传递给from_encoded_point() (x和y坐标),请参见例如here,其起始字节指示密钥是压缩格式还是未压缩格式。例如,如果要以非压缩格式传递点,则起始字节为0x04,后跟字节x坐标,然后是y坐标的字节(对于上面的示例,总长度为65个字节)。
如果没有所需格式的数据,则必须进行相应的转换(手动或编程)在传递给from_encoded_point()之前。