7

Do java.security.Key.getEncoded() returns data in DER encoded format?

If not, is there a method that do?

UPDATE: A Key interface holding an RSA private key implementation

The Student
  • 27,520
  • 68
  • 161
  • 264
  • 1
    Looking at [this](https://stackoverflow.com/a/22077915/1041046) answer, I think `PrivateKey.getEncoded()` returns `PKCS#8` format and `PublicKey.getEncoded()` returns `X509` format. – AaA Aug 17 '17 at 01:29

1 Answers1

4

Depending on the type of key. Most symmetric keys return raw bytes with no encoding. Most public keys uses ASN.1/DER encoding.

You shouldn't care about how the key is encoded. Treat getEncoded as serialization function. It returns byte-stream representation of the key, which can be saved and converted back into the key later.

For RSA private keys, it's may be encoded as PKCS#1 or PKCS#8. PKCS#1 is the preferred encoding because it contains extra CRT parameters which speed up private key operations.

Sun JCE always generates key pairs in PKCS#1 encoding so the private key is always encoded in this format defined in PKCS#1,

-- 
-- Representation of RSA private key with information for the CRT algorithm.
--
RSAPrivateKey ::= SEQUENCE {
    version           Version, 
    modulus           INTEGER,  -- n
    publicExponent    INTEGER,  -- e
    privateExponent   INTEGER,  -- d
    prime1            INTEGER,  -- p
    prime2            INTEGER,  -- q
    exponent1         INTEGER,  -- d mod (p-1)
    exponent2         INTEGER,  -- d mod (q-1) 
    coefficient       INTEGER,  -- (inverse of q) mod p
    otherPrimeInfos   OtherPrimeInfos OPTIONAL 
}

Version ::= INTEGER { two-prime(0), multi(1) }
    (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})

OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo


OtherPrimeInfo ::= SEQUENCE {
    prime             INTEGER,  -- ri
    exponent          INTEGER,  -- di
    coefficient       INTEGER   -- ti
}
ZZ Coder
  • 74,484
  • 29
  • 137
  • 169
  • please, see my update. By the way, I *need* get the data encoded in DER (its a project's specification). – The Student May 28 '10 at 18:27
  • If you are dealing with RSA private keys only, getEncoded() always returns DER encoded octet-stream. However, there are 2 different ASN.1 objects are used depending on the source of the key. – ZZ Coder May 28 '10 at 18:43
  • Thanks ZZ Coder, but is there any documentation saying that? The javadoc says nothing.. and I will need explain that to my boss, you know? :) – The Student May 28 '10 at 19:03
  • No. DER encoding is not in JCE specification so it's not guaranteed every provider will do that. However, all standard format for key storage (X.509, PKCS#12) all uses DER. It's inconceivable that provider will do something different. – ZZ Coder May 28 '10 at 19:12
  • 1
    by the way, if not asking too much, which are the 2 different ASN.1 objects used? And do you know which is used for `java.security.KeyPairGenerator.getInstance("RSA", "BC").generateKeyPair().getPrivate()`? – The Student May 28 '10 at 19:24
  • 4
    Ran a test with RSAPrivateCrtKey.getEncoded(), looks like PKCS#8 to me. – President James K. Polk May 29 '10 at 01:17
  • 7
    "*You shouldn't care about how the key is encoded. Treat getEncoded as serialization function.*" > I don't agree with this. The [documentation](http://docs.oracle.com/javase/7/docs/api/java/security/Key.html) advises that it "**is an external encoded form for the key used when a standard representation of the key is needed outside the Java Virtual Machine, as when transmitting the key to some other party.**". So the format matters on many occasions. – Duncan Jones Apr 04 '14 at 12:29
  • "You shouldn't care about how the key is encoded... can be saved and converted back into the key later". This statement is simply false. You MUST know how the key is encoded, as indicated by this answer: https://stackoverflow.com/questions/19353748/how-to-convert-byte-array-to-privatekey-or-publickey-type See Key.getFormat() to know what the format is. – Wheezil Mar 02 '19 at 21:42