Mor*_*ert 2 openssl swift apple-cryptokit x25519
假设我使用 openssl 创建一个 x25519 密钥对,它将输出一个 64 字节私钥和相应的 44 字节 Base64 编码公钥,如下所示
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIMBF8S7zUco4bRrMiIuyTcSYU/rAVlNtE8SMYWphUatw
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAE0eiiP0PKjy9AVM/0z2ZIZn453WSJNemrQ58HAXDaX0=
-----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
Swift CryptoKit 仅接受私钥和公钥初始化各 32 个字节。
如果我理解正确的话,64 字节私钥是种子,其中前 32 字节是实际私钥。
尽管如此,对公钥使用相同的原理是行不通的(这并不令人惊讶)
现在的问题是:如何将公钥转换为 Swift CryptoKit 所需的 32 字节?
这是使用 Base64 解码公钥的前 32 个字节的无效示例
let base64PublicKey = Data(base64Encoded: "MCowBQYDK2VuAyEAE0eiiP0PKjy9AVM/0z2ZIZn453WSJNemrQ58HAXDaX0=")!.dropLast(12)
let publicKey = try! Curve25519.KeyAgreement.PublicKey(rawRepresentation: rawPublicKey)
Run Code Online (Sandbox Code Playgroud)
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIMBF8S7zUco4bRrMiIuyTcSYU/rAVlNtE8SMYWphUatw
-----END PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
per rfc7468是一个 PKCS8 未加密的PrivateKeyInfo,它以ASN.1 DER编码,包含有关算法的数据(一般情况下但不是这里的参数)以及实际密钥。将其运行到openssl asn1parse -i(自动 de-base64 的)给出
0:d=0 hl=2 l= 46 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :00
5:d=1 hl=2 l= 5 cons: SEQUENCE
7:d=2 hl=2 l= 3 prim: OBJECT :X25519
12:d=1 hl=2 l= 34 prim: OCTET STRING [HEX DUMP]:0420C045F12EF351CA386D1ACC888BB24DC49853FAC056536D13C48C616A6151AB70
Run Code Online (Sandbox Code Playgroud)
算法特定的私钥是 OCTETSTRING,其值位于偏移量 12+2 和长度 34,但实际上包含嵌套的 OCTETSTRING 编码,其前两个八位位组是 04=标签和 20=长度,因此真正的私钥位于偏移量 16 和长度32——或更简单地说是最后 32 个字节。
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAE0eiiP0PKjy9AVM/0z2ZIZn453WSJNemrQ58HAXDaX0=
-----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
类似的是X.509和PKIX定义的SubjectPublicKeyInfo结构,它同样是DER并且包含除密钥之外的数据。解析它(用-dump)给出:
0:d=0 hl=2 l= 42 cons: SEQUENCE
2:d=1 hl=2 l= 5 cons: SEQUENCE
4:d=2 hl=2 l= 3 prim: OBJECT :X25519
9:d=1 hl=2 l= 33 prim: BIT STRING
0000 - 00 13 47 a2 88 fd 0f 2a-3c bd 01 53 3f d3 3d 99 ..G....*<..S?.=.
0010 - 21 99 f8 e7 75 92 24 d7-a6 ad 0e 7c 1c 05 c3 69 !...u.$....|...i
0020 - 7d
Run Code Online (Sandbox Code Playgroud)
BITSTRING 值的第一个八位字节用于未使用/填充位的数量,此处为 00,因此真正的公钥值是偏移量 9+2+1=12 处的 33-1=32 个八位字节,或者同样是最后 32 个字节。
Ed25519 对私钥进行哈希处理,生成一个 32 字节标量(有时称为种子)和一个决定公钥的 32 字节值。该种子可以与私钥一起存储,以使签名更加高效,但 OpenSSL 不会为 Ed25519 执行此操作,并且根本不适用于 X25519。
| 归档时间: |
|
| 查看次数: |
2225 次 |
| 最近记录: |