# Class PEMDecoder

java.lang.Object
java.security.PEMDecoder

public final class PEMDecoder extends Object
`PEMDecoder` is a preview API of the Java platform.
Programs can only use `PEMDecoder` when preview features are enabled.
Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.
`PEMDecoder` implements a decoder for Privacy-Enhanced Mail (PEM) data. PEM is a textual encoding used to store and transfer cryptographic objects, such as asymmetric keys, certificates, and certificate revocation lists (CRLs). It is defined in RFC 1421 and RFC 7468. PEM consists of a Base64-encoded binary encoding enclosed by a type-identifying header and footer.

The `decode(String)` and `decode(InputStream)` methods return an instance of a class that matches the PEM type and implements `DEREncodable`PREVIEW, as follows:

- CERTIFICATE : `X509Certificate`
- X509 CRL : `X509CRL`
- PUBLIC KEY : `PublicKey`
- PRIVATE KEY : `PrivateKey` or `KeyPair` (if the encoding contains a public key)
- ENCRYPTED PRIVATE KEY : `EncryptedPrivateKeyInfo`
- Other types : `PEM`PREVIEW

When used with a `PEMDecoder` instance configured for decryption:

- ENCRYPTED PRIVATE KEY : `PrivateKey` or `KeyPair` (if the encoding contains a public key)

For `PublicKey` and `PrivateKey` types, an algorithm-specific subclass is returned if the algorithm is supported. For example, an `ECPublicKey` or an `ECPrivateKey` for Elliptic Curve keys.

If the PEM type does not have a corresponding class, `decode(String)` and `decode(InputStream)` will return a `PEM` object.

The `decode(String, Class)` and `decode(InputStream, Class)` methods take a class parameter that specifies the type of `DEREncodable` to return. These methods are useful for avoiding casts when the PEM type is known, or when extracting a specific type if there is more than one option. For example, if the PEM contains both a public and private key, specifying `PrivateKey.class` returns only the private key. If the class parameter specifies `X509EncodedKeySpec.class`, the public key encoding is returned as an instance of `X509EncodedKeySpec` class. Any type of PEM data can be decoded into a `PEM` object by specifying `PEM.class`. If the class parameter does not match the PEM content, a `ClassCastException` is thrown.

In addition to the types listed above, these methods support the following PEM types and `DEREncodable` classes when specified as parameters:

- PUBLIC KEY : `X509EncodedKeySpec`
- PRIVATE KEY : `PKCS8EncodedKeySpec`
- PRIVATE KEY : `PublicKey` (if the encoding contains a public key)
- PRIVATE KEY : `X509EncodedKeySpec` (if the encoding contains a public key)

When used with a `PEMDecoder` instance configured for decryption:

- ENCRYPTED PRIVATE KEY : `PKCS8EncodedKeySpec`
- ENCRYPTED PRIVATE KEY : `PublicKey` (if the encoding contains a public key)
- ENCRYPTED PRIVATE KEY : `X509EncodedKeySpec` (if the encoding contains a public key)

A new `PEMDecoder` instance is created when configured with `withFactory(Provider)` or `withDecryption(char[])`. The `withFactory(Provider)` method uses the specified provider to produce cryptographic objects from `KeyFactory` and `CertificateFactory`. The `withDecryption(char[])` method configures the decoder to decrypt and decode encrypted private key PEM data using the given password. If decryption fails, an `IllegalArgumentException` is thrown. If an encrypted private key PEM is processed by a decoder not configured for decryption, an `EncryptedPrivateKeyInfo` object is returned. A `PEMDecoder` configured for decryption will decode unencrypted PEM.

This class is immutable and thread-safe.

Example: decode a private key:

        PEMDecoder pd = PEMDecoder.of();
        PrivateKey priKey = pd.decode(priKeyPEM, PrivateKey.class);

Example: configure decryption and a factory provider:

        PEMDecoder pd = PEMDecoder.of().withDecryption(password).
                withFactory(provider);
        DEREncodable pemData = pd.decode(privKeyPEM);

Implementation Note:
  This implementation decodes RSA PRIVATE KEY as `PrivateKey`, X509 CERTIFICATE and X.509 CERTIFICATE as `X509Certificate`, and CRL as `X509CRL`. Other implementations may recognize additional PEM types.
Since:
  25
External Specifications
  - RFC 1421: Privacy Enhancement for Internet Electronic Mail
  - RFC 5958: Asymmetric Key Packages
  - RFC 7468: Textual Encodings of PKIX, PKCS, and CMS Structures
See Also:
  - `PEMEncoder`PREVIEW
  - `PEM`PREVIEW
  - `EncryptedPrivateKeyInfo`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `DEREncodablePREVIEW`
  `decode(InputStream is)`
  Decodes and returns a `DEREncodable` from the given `InputStream`.
  `<S extends DEREncodablePREVIEW>
  S`
  `decode(InputStream is, Class<S> tClass)`
  Decodes and returns a `DEREncodable` of the specified class for the given `InputStream`.
  `DEREncodablePREVIEW`
  `decode(String str)`
  Decodes and returns a `DEREncodable` from the given `String`.
  `<S extends DEREncodablePREVIEW>
  S`
  `decode(String str, Class<S> tClass)`
  Decodes and returns a `DEREncodable` of the specified class from the given PEM string.
  `static PEMDecoderPREVIEW`
  `of()`
  Returns an instance of `PEMDecoder`.
  `PEMDecoderPREVIEW`
  `withDecryption(char[] password)`
  Returns a copy of this `PEMDecoder` that decodes and decrypts encrypted private keys using the specified password.
  `PEMDecoderPREVIEW`
  `withFactory(Provider provider)`
  Returns a copy of this `PEMDecoder` instance that uses `KeyFactory` and `CertificateFactory` implementations from the specified `Provider` to produce cryptographic objects.

  ### Methods declared in class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`
  Modifier and Type
  Method
  Description
  `protected Object`
  `clone()`
  Creates and returns a copy of this object.
  `boolean`
  `equals(Object obj)`
  Indicates whether some other object is "equal to" this one.
  `protected void`
  `finalize()`
  Deprecated, for removal: This API element is subject to removal in a future version.
  Finalization is deprecated and subject to removal in a future release.
  `final Class<?>`
  `getClass()`
  Returns the runtime class of this `Object`.
  `int`
  `hashCode()`
  Returns a hash code value for this object.
  `final void`
  `notify()`
  Wakes up a single thread that is waiting on this object's monitor.
  `final void`
  `notifyAll()`
  Wakes up all threads that are waiting on this object's monitor.
  `String`
  `toString()`
  Returns a string representation of the object.
  `final void`
  `wait()`
  Causes the current thread to wait until it is awakened, typically by being notified or interrupted.
  `final void`
  `wait(long timeoutMillis)`
  Causes the current thread to wait until it is awakened, typically by being notified or interrupted, or until a certain amount of real time has elapsed.
  `final void`
  `wait(long timeoutMillis, int nanos)`
  Causes the current thread to wait until it is awakened, typically by being notified or interrupted, or until a certain amount of real time has elapsed.

- ## Method Details

  - ### of

    public static PEMDecoderPREVIEW of()
    Returns an instance of `PEMDecoder`.
    Returns:
      a `PEMDecoder` instance

  - ### decode

    public DEREncodablePREVIEW decode(String str)
    Decodes and returns a `DEREncodable` from the given `String`.

    This method reads the `String` until PEM data is found or the end of the `String` is reached. If no PEM data is found, an `IllegalArgumentException` is thrown.

    A `DEREncodable` will be returned that best represents the decoded data. If the PEM type is not supported, a `PEM` object is returned containing the type identifier, Base64-encoded data, and any leading data preceding the PEM header. For `DEREncodable` types other than `PEM`, leading data is ignored and not returned as part of the `DEREncodable` object.

    Input consumed by this method is read in as `UTF-8`.

    Parameters:
      `str` - a `String` containing PEM data
    Returns:
      a `DEREncodable`
    Throws:
      `IllegalArgumentException` - on error in decoding or no PEM data found
      `NullPointerException` - when `str` is `null`

  - ### decode

    public DEREncodablePREVIEW decode(InputStream is) throws IOException
    Decodes and returns a `DEREncodable` from the given `InputStream`.

    This method reads from the `InputStream` until the end of a PEM footer or the end of the stream. If an I/O error occurs, the read position in the stream may become inconsistent. It is recommended to perform no further decoding operations on the `InputStream`.

    A `DEREncodable` will be returned that best represents the decoded data. If the PEM type is not supported, a `PEM` object is returned containing the type identifier, Base64-encoded data, and any leading data preceding the PEM header. For `DEREncodable` types other than `PEM`, leading data is ignored and not returned as part of the `DEREncodable` object.

    If no PEM data is found, an `EOFException` is thrown.

    Parameters:
      `is` - `InputStream` containing PEM data
    Returns:
      a `DEREncodable`
    Throws:
      `IOException` - on IO or PEM syntax error where the `InputStream` did not complete decoding
      `EOFException` - no PEM data found or unexpectedly reached the end of the `InputStream`
      `IllegalArgumentException` - on error in decoding
      `NullPointerException` - when `is` is `null`

  - ### decode

    public <S extends DEREncodablePREVIEW> S decode(String str, Class<S> tClass)
    Decodes and returns a `DEREncodable` of the specified class from the given PEM string. `tClass` must be an appropriate class for the PEM type.

    This method reads the `String` until PEM data is found or the end of the `String` is reached. If no PEM data is found, an `IllegalArgumentException` is thrown.

    If the class parameter is `PEM.class`, a `PEM` object is returned containing the type identifier, Base64-encoded data, and any leading data preceding the PEM header. For `DEREncodable` types other than `PEM`, leading data is ignored and not returned as part of the `DEREncodable` object.

    Input consumed by this method is read in as `UTF-8`.

    Type Parameters:
      `S` - class type parameter that extends `DEREncodable`
    Parameters:
      `str` - the `String` containing PEM data
      `tClass` - the returned object class that extends or implements `DEREncodable`
    Returns:
      a `DEREncodable` specified by `tClass`
    Throws:
      `IllegalArgumentException` - on error in decoding or no PEM data found
      `ClassCastException` - if `tClass` does not represent the PEM type
      `NullPointerException` - when any input values are `null`

  - ### decode

    public <S extends DEREncodablePREVIEW> S decode(InputStream is, Class<S> tClass) throws IOException
    Decodes and returns a `DEREncodable` of the specified class for the given `InputStream`. `tClass` must be an appropriate class for the PEM type.

    This method reads from the `InputStream` until the end of a PEM footer or the end of the stream. If an I/O error occurs, the read position in the stream may become inconsistent. It is recommended to perform no further decoding operations on the `InputStream`.

    If the class parameter is `PEM.class`, a `PEM` object is returned containing the type identifier, Base64-encoded data, and any leading data preceding the PEM header. For `DEREncodable` types other than `PEM`, leading data is ignored and not returned as part of the `DEREncodable` object.

    If no PEM data is found, an `EOFException` is thrown.

    Type Parameters:
      `S` - class type parameter that extends `DEREncodable`
    Parameters:
      `is` - an `InputStream` containing PEM data
      `tClass` - the returned object class that extends or implements `DEREncodable`
    Returns:
      a `DEREncodable` typecast to `tClass`
    Throws:
      `IOException` - on IO or PEM syntax error where the `InputStream` did not complete decoding
      `EOFException` - no PEM data found or unexpectedly reached the end of the `InputStream`
      `IllegalArgumentException` - on error in decoding
      `ClassCastException` - if `tClass` does not represent the PEM type
      `NullPointerException` - when any input values are `null`
    See Also:
      - `decode(InputStream)`
      - `decode(String, Class)`

  - ### withFactory

    public PEMDecoderPREVIEW withFactory(Provider provider)
    Returns a copy of this `PEMDecoder` instance that uses `KeyFactory` and `CertificateFactory` implementations from the specified `Provider` to produce cryptographic objects. Any errors using the `Provider` will occur during decoding.
    Parameters:
      `provider` - the factory provider
    Returns:
      a new `PEMDecoder` instance configured with the `Provider`
    Throws:
      `NullPointerException` - if `provider` is `null`

  - ### withDecryption

    public PEMDecoderPREVIEW withDecryption(char[] password)
    Returns a copy of this `PEMDecoder` that decodes and decrypts encrypted private keys using the specified password. Non-encrypted PEM can also be decoded from this instance.
    Parameters:
      `password` - the password to decrypt the encrypted PEM data. This array is cloned and stored in the new instance.
    Returns:
      a new `PEMDecoder` instance configured for decryption
    Throws:
      `NullPointerException` - if `password` is `null`