如何将openssl创建的44字节x25519公钥传递给CryptoKit,该公钥需要32字节的密钥长度



假设我使用openssl创建了一个x25519密钥对,它将输出一个64字节的私钥和相应的44字节Base64编码的公钥,看起来像

-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIMBF8S7zUco4bRrMiIuyTcSYU/rAVlNtE8SMYWphUatw
-----END PRIVATE KEY-----

-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAE0eiiP0PKjy9AVM/0z2ZIZn453WSJNemrQ58HAXDaX0=
-----END PUBLIC KEY-----

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) 
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIMBF8S7zUco4bRrMiIuyTcSYU/rAVlNtE8SMYWphUatw
-----END PRIVATE KEY-----

per-rfc7468是一个PKCS8未加密的PrivateKeyInfo,它被编码在ASN.1 DER中,并包含关于算法的数据(通常但这里不是参数(以及实际密钥。将其运行到openssl asn1parse -i(它会自动去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

特定于算法的私钥是OCETSTRING,其值在偏移12+2处,长度为34,但它实际上包含嵌套的OCETSTRIN编码,其前两个八位字节为04=标记和20=长度,因此真正的私钥在偏移16处,长度32,或者更简单地说是最后32个字节。

-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAE0eiiP0PKjy9AVM/0z2ZIZn453WSJNemrQ58HAXDaX0=
-----END PUBLIC KEY-----

类似地是由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

BITSTRING值的第一个八位位组用于未使用/填充位的数量,这里为00,因此真正的公钥值是偏移量9+2+1=12处的33-1=32个八位位位组,或者再次是最后32个字节。


Ed25519对私钥进行散列处理,以产生一个32字节的标量(有时称为种子(和一个确定公钥的32字节值。这个种子可以与私钥一起存储,以提高签名效率,但OpenSSL对Ed25519没有这样做,而且它根本不适用于X25519。

相关内容

  • 没有找到相关文章

最新更新