如何使用加密技术在Python中使用Kotlin PublicKey对象加载编码的公钥

2024-06-16 09:58:14 发布

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

我目前在加载Python中从Kotlin“提取”的公钥时遇到问题。我试图在Kotlin和Python之间创建一个功能性的X25519 EDH,所以我需要在Python中加载Kotlin代码创建的公钥。另一种方法也行

我的Kotlin代码如下所示

class EllipticDiffieHellman {
    private val keyPairGenerator = KeyPairGenerator.getInstance("XDH")
    private val parameters = NamedParameterSpec("X25519")
    private val keyAgreement = KeyAgreement.getInstance("XDH")
    private val keyFactory = KeyFactory.getInstance("XDH")

    fun generateKeyPair() : KeyPair {
        keyPairGenerator.initialize(parameters)
        return keyPairGenerator.generateKeyPair()
    }

    fun getKeyShare(keyPair: KeyPair) : ByteArray = keyPair.public.encoded

    fun bytesToPubKey(keyShare: ByteArray) : PublicKey = keyFactory.generatePublic(X509EncodedKeySpec(keyShare))

    fun getSharedKey(keyPair: KeyPair, keyShare: PublicKey) : ByteArray {
        keyAgreement.init(keyPair.private)
        keyAgreement.doPhase(keyShare, true)
        return keyAgreement.generateSecret()
    }
}

...

    val EDH = EllipticDiffieHellman()
    val keypair_python = EDH.generateKeyPair()
    File("keyshare_kotlin").writeBytes(EDH.getKeyShare(keypair_python))

当我尝试使用bytesToPubKey加载相同的ByteArray时,一切都正常。 现在来看我的Python代码(它的一部分):

import cryptography.hazmat.primitives.serialization as serialization
with open("keyshare_kotlin", "rb") as f:
    keyshare_kotlin = f.read()
loaded_public_key = serialization.load_der_public_key(keyshare_kotlin)

这不管用。我一直在尝试使用其他cryptography的加载函数,但都不起作用

我得到了ValueError: Could not deserialize key data. The data may be in an incorrect format or it may be encrypted with an unsupported algorithm.

谢谢你的帮助


Tags: 代码valprivateedhfunxdhbytearraykotlin
1条回答
网友
1楼 · 发布于 2024-06-16 09:58:14

我找到了一个有效的解决方案,尽管正如评论中提到的那样——它不是最优的

Kotlin/Java生成的字节使用与Python生成的字节不同的头。Kotlin的头是14字节长,Python的头是12字节长。这是编码公钥的这两个“版本”之间的唯一区别,虽然Python能够加载12字节的头,但它无法加载Kotlin的14字节头

使用从使用密码学的.public_key().public_bytes(serialization.DER, serialization.SubjectPublicKeyInfo)编码的字节中提取的头,并用它替换Kotlin生成的头,就可以在Python中加载编码的字节

import cryptography.hazmat.primitives.asymmetric.x25519 as x25519
import cryptography.hazmat.primitives.serialization as serialization

private_key = x25519.X25519PrivateKey.generate()
public_bytes = private_key.public_bytes(
        encoding=serialization.Encoding.DER,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
)

with open("keyshare_kotlin", "rb") as f:
        keyshare_kotlin = f.read()
loaded_keyshare = serialization.load_der_public_key(public_bytes[:12] + keyshare_kotlin[14:])

相关问题 更多 >