# 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 security 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-formatted 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 data type and implements `DEREncodable`PREVIEW.

The following lists the supported PEM types and the `DEREncodable` types that each are decoded as:

- CERTIFICATE : `X509Certificate`
- X509 CRL : `X509CRL`
- PUBLIC KEY : `PublicKey`
- PUBLIC KEY : `X509EncodedKeySpec` (Only supported when passed as a `Class` parameter)
- PRIVATE KEY : `PrivateKey`
- PRIVATE KEY : `PKCS8EncodedKeySpec` (Only supported when passed as a `Class` parameter)
- PRIVATE KEY : `KeyPair` (if the encoding also contains a public key)
- ENCRYPTED PRIVATE KEY : `EncryptedPrivateKeyInfo`
- ENCRYPTED PRIVATE KEY : `PrivateKey` (if configured with Decryption)
- Other types : `PEMRecord`

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

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

The decode(String, Class) and decode(InputStream, Class) methods take a class parameter which determines the type of `DEREncodable` that is returned. These methods are useful when extracting or changing the return class. For example, if the PEM contains both public and private keys, the class parameter can specify which to return. Use `PrivateKey.class` to return only the private key. If the class parameter is set to `X509EncodedKeySpec.class`, the public key will be returned in that format. Any type of PEM data can be decoded into a `PEMRecord` by specifying `PEMRecord.class`. If the class parameter doesn't match the PEM content, a ClassCastException will be thrown.

A new `PEMDecoder` instance is created when configured with withFactory(Provider) and/or withDecryption(char[]). withFactory(Provider) configures the decoder to use only KeyFactory and CertificateFactory instances from the given `Provider`. withDecryption(char[]) configures the decoder to decrypt all encrypted private key PEM data using the given password. Configuring an instance for decryption does not prevent decoding with unencrypted PEM. Any encrypted PEM that fails decryption will throw a `RuntimeException`. When an encrypted private key PEM is used with a decoder not configured for decryption, an `EncryptedPrivateKeyInfo` object is returned.

This class is immutable and thread-safe.

Here is an example of decoding a `PrivateKey` object:

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

Here is an example of a `PEMDecoder` configured with decryption and a factory provider:

        PEMDecoder pd = PEMDecoder.of().withDecryption(password).
            withFactory(provider);
        byte[] pemData = pd.decode(privKey);

Implementation Note:
  An implementation may support other PEM types and `DEREncodable` objects. This implementation additionally supports the following PEM types: `X509 CERTIFICATE`, `X.509 CERTIFICATE`, `CRL`, and `RSA PRIVATE KEY`.
Since:
  25
External Specifications
  - RFC 1421: Privacy Enhancement for Internet Electronic Mail
  - RFC 7468: Textual Encodings of PKIX, PKCS, and CMS Structures
See Also:
  - `PEMEncoder`PREVIEW
  - `PEMRecord`PREVIEW
  - `EncryptedPrivateKeyInfo`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `DEREncodablePREVIEW`
  `decode(InputStream is)`
  Decodes and returns a `DEREncodable`PREVIEW from the given `InputStream`.
  `<S extends DEREncodablePREVIEW>
  S`
  `decode(InputStream is, Class<S> tClass)`
  Decodes and returns the specified class for the given `InputStream`.
  `DEREncodablePREVIEW`
  `decode(String str)`
  Decodes and returns a `DEREncodable`PREVIEW 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`

- ## 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`PREVIEW 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.

    This method returns a Java API cryptographic object, such as a `PrivateKey`, if the PEM type is supported. Any non-PEM data preceding the PEM header is ignored by the decoder. Otherwise, a `PEMRecord`PREVIEW will be returned containing the type identifier and Base64-encoded data. Any non-PEM data preceding the PEM header will be stored in `leadingData`.

    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`PREVIEW from the given `InputStream`.

    This method reads from the `InputStream` until the end of the 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`.

    This method returns a Java API cryptographic object, such as a `PrivateKey`, if the PEM type is supported. Any non-PEM data preceding the PEM header is ignored by the decoder. Otherwise, a `PEMRecord`PREVIEW will be returned containing the type identifier and Base64-encoded data. Any non-PEM data preceding the PEM header will be stored in `leadingData`.

    If no PEM data is found, an `IllegalArgumentException` 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` - at 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 extend `DEREncodable`PREVIEW and 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 `PEMRecord.class`, a PEMRecord is returned containing the type identifier and Base64 encoding. Any non-PEM data preceding the PEM header will be stored in `leadingData`. Other class parameters will not return preceding non-PEM data.

    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 implements `DEREncodable`
    Returns:
      a `DEREncodable` specified by `tClass`
    Throws:
      `IllegalArgumentException` - on error in decoding or no PEM data found
      `ClassCastException` - if `tClass` is invalid for 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 the specified class for the given `InputStream`. The class must extend `DEREncodable`PREVIEW and be an appropriate class for the PEM type.

    This method reads from the `InputStream` until the end of the 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 `PEMRecord.class`, a PEMRecord is returned containing the type identifier and Base64 encoding. Any non-PEM data preceding the PEM header will be stored in `leadingData`. Other class parameters will not return preceding non-PEM data.

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

    Type Parameters:
      `S` - Class type parameter that extends `DEREncodable`.
    Parameters:
      `is` - an InputStream containing PEM data
      `tClass` - the returned object class that implements `DEREncodable`.
    Returns:
      a `DEREncodable` typecast to `tClass`
    Throws:
      `IOException` - on IO or PEM syntax error where the `InputStream` did not complete decoding.
      `EOFException` - at the end of the `InputStream`
      `IllegalArgumentException` - on error in decoding
      `ClassCastException` - if `tClass` is invalid for 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 PEMEncoder instance configured to 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 still be decoded from this instance.
    Parameters:
      `password` - the password to decrypt encrypted PEM data. This array is cloned and stored in the new instance.
    Returns:
      a new PEMEncoder instance configured for decryption
    Throws:
      `NullPointerException` - if `password` is null