1

I generate private key this way:

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

And im getting 144 length private key. Then i convert my private key to PKCS1 format:

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

In come cases i need to convert pkcs1 back to pkcs8. And that's unclear for me. Cannot find any working solution. Is it even possible?

P.S. pkcs8 to pkcs1 convertion was found here

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
TooLazy
  • 836
  • 4
  • 11
  • 29
  • PKCS#1 defines a RSA format. You're probably using a X9.62 formatted private key. PKCS#8 contains this key, so it would probably be easier to convert it to X9.62 than the other way around/ – Maarten Bodewes Oct 29 '18 at 23:14
  • Not sure i understand you. According to secp256k1 my original private key is not X9.62 formatted. Or do you mean PKCS1 formatted key? – TooLazy Oct 30 '18 at 07:30
  • Again, PKCS#1 doesn't play a role here. PKCS#1 stands for Public Key Crypto Standard from RSA laboratories. #1 specifies RSA itself. You can read the RFC online. It has literally nothing to do with ECC. Only RSA public and priate keys can be stored using PKCS#1, and those can be wrapped with PKCS#8 to indicate the key type and possibly to encrypt them. PKCS#8 an also be used to wrap other formats though, such as X9.62 keys, which are commonly Prime curves or Koblitz curves. – Maarten Bodewes Oct 30 '18 at 18:45
  • Thnx, but i still cannot figure out what to do in my case. – TooLazy Oct 31 '18 at 10:01

1 Answers1

1

As indicated, the private key is in X9.62 format. It cannot be in PKCS#1 format because that format specifies RSA, not ECC.

Furthermore, your PKCS#8 private key contains more information than the X9.62 formatted private key that you've extracted from it. You can see the decoding of 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 ...

The internal X9.62 key is the sequence within the octet string and the secret (S) is the 32 byte octet string.

So you have to add back the information. This is an AlgorithmIdentifier that indicates ecPublicKey operations as well as the curve used (repeated for the public key).

So without further ado, the operations to recreate the PKCS#8 structure (with x962 replacing pkcs1):

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

note that this is the non-encrypted variant of PKCS#8 which just shows the private key type. The encrypted variant encrypts this structure and adds information on the used wrapping mechanism (e.g. AES encrypted).

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • I'll let you replace the type with `val`, remove the `new` keyword and of course strip of the final semicolons, if you don't mind. – Maarten Bodewes Nov 01 '18 at 21:50
  • I know it seems like I'm stalking you, but was privatekey ASN.1 added to X9.62? Having not shelled out moolah I have only a draft of -1999, but SECG:SEC1v2-2009 cites parameters, publickey and signature to rfc3279-2002 and rfc5480-2009 which in turn respectively cite X9.62-1999 and -2005, but neither SEC1 nor rfc5915-2010 cites privatekey; SEC1 defines (near-trivial) i2os directly while rfc5915 cites rfc3447=PKCS1v2.1. I have therefore been citing SEC1 for EC privatekey format. (I concur it's not PKCS1 of course.) – dave_thompson_085 Nov 02 '18 at 01:01
  • I haven't got it either, I suppose the RFC has taken it from SEC1 v2, section C4. I just assumed X9.62 because it is in the PKCS#8 as OID. However, it may be that SEC1 just reused the existing OID for the private key format and that X9.62 doesn't specify it at all. It isn't really required for performing ECC operations after all. – Maarten Bodewes Nov 02 '18 at 01:48