python - 输出 SecKeyCopyExternalRepresentation

标签 python swift cryptography public-key public-key-exchange

我正在尝试将公钥从我的 iPhone 传递给其他方,但是我无法使用 iOS 的输出。

let parameters: [String: Any] = [
    kSecAttrKeySizeInBits as String: 384,
    kSecAttrKeyType as String: kSecAttrKeyTypeEC,
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String: false
    ]
]

var error: Unmanaged<CFError>?
let privateKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error)
let publicKey = SecKeyCopyPublicKey(privateKey!)

let pub = SecKeyCopyExternalRepresentation(publicKey!, &error)
let pubData = pub as Data?
print(pubData!.base64EncodedString())

示例输出:

BJSCZtBatd2BYEHtyLB0qTZNlphKf3ZTGI6Nke3dSxIDpyP9FWMZbG0zcdIXWENyndskfxV0No/yz369ngL2EHZYw6ggNysOnZ5IQSPOLFFl44m1aAk0o0NdaRXTVAz4jQ==

在 python 中(我的第二方所在的位置)我有以下内容:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

pub_key = serialisation.load_pem_public_key(
    data=xcode_data.encode(),
    backend=default_backend()
)

我得到的错误是ValueError: Could not deserialize key data.

那么文档中描述的 SecKeyCopyExternalRepresentation 的输出到底是什么:

The method returns data in the PCKS #1 format for an RSA key. For an elliptic curve public key, the format follows the ANSI X9.63 standard using a byte string of 04 || X || Y. For an elliptic curve private key, the output is formatted as the public key concatenated with the big endian encoding of the secret scalar, or 04 || X || Y || K. All of these representations use constant size integers, including leading zeros as needed.

如何描述X6.93 格式?我该如何将它转换成我可以在 python 代码中使用的东西?

附言我试图将诸如 -----BEGIN PUBLIC KEY----- 之类的 header 添加到 xcode 输出中。

最佳答案

我还没有完全找到问题的答案,因为我仍然不知道 Apple 提供的输出到底是什么,但是,我想出了一个解决方案,在 this key import export manager 中找到了.

let parameters: [String: Any] = [
    kSecAttrKeySizeInBits as String: 384,
    kSecAttrKeyType as String: kSecAttrKeyTypeEC,
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String: false
    ]
]

var pubKey: SecKey?
var priKey: SecKey?
var error: Unmanaged<CFError>?
let keyPair = SecKeyGeneratePair(parameters as CFDictionary, &pubKey, &priKey)

let publicKeyData = SecKeyCopyExternalRepresentation(pubKey!, &error)
// Code from the library
let ieManager = CryptoExportImportManager()
if let exportPEM = ieManager.exportPublicKeyToPEM(publicKeyData as Data!, keyType: kSecAttrKeyTypeEC as String, keySize: 384) {
    print(exportPEM)
} else {
    print("Error exporting to PEM")
}

示例输出:

Exporting EC raw key: 97 bytes -----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEFpCnTrJFQq0mZBvy+vzl9noKLZ4/s1cf I6hygug6s8dvBreMhabAcAbbhSa1losjCxV450nq92W9ZymonYasaAuhshDWjmvx 2qTXHEpVEVb9GawqX6XqpWtIBf+meHKS -----END PUBLIC KEY-----

Python 中的实现 using cryptography

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

xcode = '-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEFpCnTrJFQq0mZBvy+vzl9noKLZ4/s1cf\nI6hygug6s8dvBreMhabAcAbbhSa1losjCxV450nq92W9ZymonYasaAuhshDWjmvx2\nqTXHEpVEVb9GawqX6XqpWtIBf+meHKS\n-----END PUBLIC KEY-----'
pub_key = serialization.load_pem_public_key(xcode.encode(), default_backend())
xcode

输出如下: <cryptography.hazmat.backends.openssl.ec._EllipticCurvePublicKey object at 0x7fb4f6f50e10>

请注意,您必须自己在 python 中添加新行才能使这一切正常工作。

更新

SecKeyCopyExternalRepresentation 的输出ECC key 是 key 的 X9.62 或 X9.63 格式(未压缩形式)。这与 DER 和 PEM 编码有很大不同。

编码为04 || X || Y用于公钥和 04 || X || Y || K对于私钥。 04是这种格式的固定字节。 X , Y和可选的 K值是定义此键的曲线的点或坐标。有关更多信息 here .

关于python - 输出 SecKeyCopyExternalRepresentation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49967723/

相关文章:

xcode - class func,这在 Xcode 中意味着什么以及为什么 self 在其中从 myClass 更改为 myClass.Type

ruby - PBEWithMD5AndDES 在 Ruby 中的实现

security - 为什么好的散列算法不允许攻击者找到产生相同散列的两条消息?

java - 如何在 Java 中存储和重用 key 对?

python - 使用turtle.onscreenclick查找鼠标单击的坐标

python - Pandas 转换日期时间格式

使用嵌套键的 Python 递归搜索 Dict

python - Lame MP3 Converter 的 Python 等价物是什么?

ios - 增加 SKShader 中的统一值

ios - 使用 Kingfisher 的 Swift iOS 照片采集会导致内存增长