Kotlin 将 PKCS1 转换为 PKCS8
Kotlin convert PKCS1 to PKCS8
我这样生成私钥:
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。发现 pkcs8 到 pkcs1 的转换 here
如图所示,私钥为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
操作 以及使用的曲线(对 public 键重复)。
所以事不宜迟,重新创建 PKCS#8 结构的操作(用 x962
替换 pkcs1
):
ASN1Primitive prim = ASN1Primitive.fromByteArray(x962);
PrivateKeyInfo keyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(
X9ObjectIdentifiers.id_ecPublicKey,
SECObjectIdentifiers.secp256k1), prim);
请注意,这是 PKCS#8 的非加密变体,它只显示私钥类型。加密变体加密此结构并添加有关使用的包装机制的信息(例如 AES 加密)。
我这样生成私钥:
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。发现 pkcs8 到 pkcs1 的转换 here
如图所示,私钥为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
操作 以及使用的曲线(对 public 键重复)。
所以事不宜迟,重新创建 PKCS#8 结构的操作(用 x962
替换 pkcs1
):
ASN1Primitive prim = ASN1Primitive.fromByteArray(x962);
PrivateKeyInfo keyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(
X9ObjectIdentifiers.id_ecPublicKey,
SECObjectIdentifiers.secp256k1), prim);
请注意,这是 PKCS#8 的非加密变体,它只显示私钥类型。加密变体加密此结构并添加有关使用的包装机制的信息(例如 AES 加密)。