Kotlin将PKCS1转换为PKCS8

时间:2018-10-29 12:46:44

标签: java encryption kotlin private-key pkcs#8

我以这种方式生成私钥:

val keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "SC")
val spec = ECGenParameterSpec("secp256k1")
keyPairGenerator.initialize(spec, SecureRandom())
keyPairGenerator.genKeyPair()
val kp = keyPairGenerator.generateKeyPair()

并且正在获得144长度的私钥。然后,我将私钥转换为PKCS1格式:

val pkInfo = PrivateKeyInfo.getInstance(kp.private.encoded)
val encodable = pkInfo.parsePrivateKey()
val primitive = encodable.toASN1Primitive()
val pkcs1 = primitive.encoded //118 length here

在某些情况下,我需要将pkcs1转换回pkcs8。这对我来说还不清楚。找不到任何有效的解决方案。甚至有可能吗?

P.S。发现here

从pkcs8到pkcs1的转换

1 个答案:

答案 0 :(得分:1)

如所示,私钥为X9.62格式。不能采用PKCS#1格式,因为该格式指定的是RSA,而不是ECC。

此外,与从中提取的X9.62格式的私钥相比,您的PKCS#8私钥包含的更多信息。您可以看到PKCS#8 here的解码:

SEQUENCE (3 elem)
  INTEGER 0
  SEQUENCE (2 elem)
    OBJECT IDENTIFIER 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public key type)
    OBJECT IDENTIFIER 1.3.132.0.10 secp256k1 (SECG (Certicom) named elliptic curve)
  OCTET STRING (1 elem)
    SEQUENCE (4 elem)
      INTEGER 1
      OCTET STRING (32 byte) 9CDDA50E9E839066257291DBCBDBD9A8A177F350AA522A128163AB7E955622C5
      [0] (1 elem)
        OBJECT IDENTIFIER 1.3.132.0.10 secp256k1 (SECG (Certicom) named elliptic curve)
      [1] (1 elem)
        BIT STRING (520 bit) ... the optional public key ...

内部X9.62密钥是八位字节字符串内的序列 ,而秘密(S)是32字节八位字节字符串。

因此,您必须添加回信息。这是AlgorithmIdentifier,指示ecPublicKey 操作以及所使用的曲线(对于公钥重复)。

因此,事不宜迟,重新创建PKCS#8结构的操作(用x962代替了pkcs1):

ASN1Primitive prim = ASN1Primitive.fromByteArray(x962);
PrivateKeyInfo keyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(
        X9ObjectIdentifiers.id_ecPublicKey,
        SECObjectIdentifiers.secp256k1), prim);

请注意,这是PKCS#8的未加密变体,仅显示私钥类型。加密的变体对这种结构进行加密,并在使用的包装机制上添加信息(例如AES加密)。