如何用PyCryptodome实现Google Tink的computeEciesHkdfSymmetricKey方法
需求背景
我正在使用Python和PyCryptodome开发Google Tink库中paymentmethodtoken模块的Python版本,用于处理GPay报文。目前需要实现与Java版kem函数等效的Python逻辑。
参考代码
Java版kem实现
private byte[] kem(JsonObject json, final byte[] contextInfo) throws GeneralSecurityException { int demKeySize = protocolVersionConfig.aesCtrKeySize + protocolVersionConfig.hmacSha256KeySize; byte[] ephemeralPublicKey = Base64.decode( json.get(PaymentMethodTokenConstants.JSON_EPHEMERAL_PUBLIC_KEY).getAsString()); byte[] sharedSecret = recipientKem.computeSharedSecret(ephemeralPublicKey); return Hkdf.computeEciesHkdfSymmetricKey( ephemeralPublicKey, sharedSecret, PaymentMethodTokenConstants.HMAC_SHA256_ALGO, PaymentMethodTokenConstants.HKDF_EMPTY_SALT, contextInfo, demKeySize); }
Python半成品代码
def __kem(self, signed_message: SignedMessage, context_info: bytearray) -> bytearray: dem_key_size: int = 64 ephemeral_public_key: bytes = base64.b64decode(signed_message.ephemeral_public_key) shared_secret: bytearray = self.__compute_shared_secret(bytearray(ephemeral_public_key)) empty_salt: bytearray = bytearray() # to do return self.__compute_ecies_hkdf_symmetric_key(ephemeral_public_key, shared_secret, empty_salt, context_info, dem_key_size)
def __compute_ecies_hkdf_symmetric_key(self, ephemeral_public_key: bytes, shared_secret: bytearray, salt: bytearray, context_info: bytearray, dem_key_size: int) -> bytearray: # TODO: add function body hkdf_input: bytes = ephemeral_public_key + shared_secret key1, key2 = HKDF(master=bytes("something goes here", "utf-8"), hashmod=SHA256, salt=salt, key_len=dem_key_size) pass
疑问说明
根据查阅的源码,Google Tink的computeEciesHkdfSymmetricKey逻辑和PyCryptodome现有HKDF实现逻辑不一致,有两个疑问:
- PyCryptodome或者其他Python库中有没有该方法的现成实现?
- 如果没有现成实现,能不能手动复现其逻辑?
解决方案
没有直接对应的封装好的现成方法,但手动复现非常简单。
Tink的computeEciesHkdfSymmetricKey和标准HKDF的唯一差异是输入密钥材料的预处理逻辑:需要先把临时公钥和共享密钥拼接,再作为HKDF的输入密钥材料,后续的HKDF导出逻辑完全符合标准,直接用PyCryptodome的HKDF实现即可。
修改后的__compute_ecies_hkdf_symmetric_key代码如下:
from Crypto.Protocol.KDF import HKDF from Crypto.Hash import SHA256 def __compute_ecies_hkdf_symmetric_key(self, ephemeral_public_key: bytes, shared_secret: bytearray, salt: bytearray, context_info: bytearray, dem_key_size: int) -> bytearray: # 拼接得到HKDF的输入密钥材料 ikm = ephemeral_public_key + shared_secret # 调用PyCryptodome标准HKDF实现 hkdf_result = HKDF( master=ikm, key_len=dem_key_size, salt=bytes(salt), hashmod=SHA256, context=bytes(context_info) ) return bytearray(hkdf_result)
如果需要拆分AES密钥和HMAC密钥,直接按长度切分返回结果即可:比如dem_key_size为64时,前32字节是AES-CTR密钥,后32字节是HMAC-SHA256密钥,和Java版的密钥拆分逻辑完全对齐。
内容的提问来源于stack exchange,提问作者Bastien B
相关产品推荐
相关产品推荐

