当前位置: 首页 > 知识库问答 >
问题:

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

樊运乾
2023-03-14

假设我使用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字节是实际的私钥。

尽管如此,对公钥使用相同的原理是行不通的(不是很令人惊讶的tbh)

现在的问题是:如何将公钥转换为 Swift CryptoKit 所需的 32 字节?

下面是使用 base64 解码公钥的前 32 个字节的非功能示例

let base64PublicKey = Data(base64Encoded: "MCowBQYDK2VuAyEAE0eiiP0PKjy9AVM/0z2ZIZn453WSJNemrQ58HAXDaX0=")!.dropLast(12)

let publicKey = try! Curve25519.KeyAgreement.PublicKey(rawRepresentation: rawPublicKey) 

共有1个答案

郑俊彦
2023-03-14
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIMBF8S7zUco4bRrMiIuyTcSYU/rAVlNtE8SMYWphUatw
-----END PRIVATE KEY-----

per rfc7468是一个PKCS8未加密的Private ateKeyInfo,它以ASN.1 DER编码,包含有关算法的数据(以及一般但不是这里的参数)以及实际密钥。将其运行到openssl asn1parse-i(自动de-base 64)中给出

    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

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

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

类似的是由X.509和PKIX定义的SubjectPublicKeyInfo结构,它类似于DER,除了密钥之外还包含数据。对其进行分析(使用<code>-dump</code>)得到:

    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对privatekey进行散列,以生成一个32字节的标量(有时称为种子)和一个确定公钥的32字节值。此种子可以与privatekey一起存储,以提高签名效率,但OpenSSL对Ed25519不起作用,而且它根本不适用于X25519。

 类似资料:
  • 问题内容: 我无法在上创建索引。 MySQL: 问题答案:

  • 问题内容: 当我执行以下命令时: 我收到此错误消息: 有关column1和column2的信息: 我认为只需要21个字节,而只需要501个字节。因此,总字节数是522,少于767。那么为什么收到错误消息? 问题答案: 在MySQL版本5.6(及更早版本)中,InnoDB表的前缀限制为767个字节。MyISAM表的长度为1,000字节。在MySQL 5.7及更高版本中,此限制已增加到3072字节。

  • 问题内容: 我知道有关此标题的问题已经回答过,但是请继续阅读。发布前,我已彻底阅读了关于此错误的所有其他问题/答案。 我收到以下查询的上述错误: 有谁知道为什么以及如何解决它?问题是-相同的查询在我的本地计算机上运行完美,在我以前的主机上也运行良好。顺便说一句,它来自一个成熟的项目- phpdevshell-所以我猜这些家伙知道他们在做什么,尽管你永远都不知道。 任何线索表示赞赏。 我正在使用ph

  • 问题内容: 原因 我该怎么办? 这是我的数据库编码: 问题答案: 这仅仅是一个MySQL问题- MySQL具有不同的引擎-MyISAM,InnoDB,内存… MySQL对可用于在列上定义索引的空间量有不同的限制- MyISAM为1,000字节;对于InnoDB是767 。这些列的数据类型很重要- 例如,它是3倍,因此a上的索引将占用其中300个字节(因为100个字符* 3 = 300)。 为了在达

  • 问题内容: 我正在使用Rails 2.3.5应用程序,在女巫中我有这个领域 而这个指数 当我尝试执行时: 我收到此错误,并且不太了解如何解决。 问题答案: 听起来好像默认排序规则使用UTF8字符集。 MySQL通过字节而不是字符来限制键的长度。由于MySQL使用的UTF8实现每个字符允许3个字节,因此UTF8列上键的最大长度是键长度(以字符为单位)的3倍(如果未明确指定,则键长度为字段的全长)。