Skip to main content

mTLS with Digital Signature

Depending on the API capability, the use of a mTLS with a Digital Signature may be required. This article provides instructions for making requests to J.P. Morgan APIs by using mTLS and a Digital Signature, if applicable.

Before you start

It is required you have:

  • An account on the J.P. Morgan Payments Developer Portal; instructions are available here.
  • Created a developer project and added API products.

To invoke an API call, you must belong to a JPMC client organization and obtain security credentials, including a client certificate and private key. After activating your account, you will see your dashboard and be ready to proceed.

Note

You must have an API Security role in order to upload certificates and manage your organization credentials.

Generate a signed certificate

Generate an authority-signed certificate through a Certificate Authority (CA) or a self-signed certificate using the J.P. Morgan authentication utility or OpenSSL. For detailed instructions, see Authentication.

Add your mTLS certificate

Provide the public key certificate for the mTLS credential:

  1. In the Payments Developer Portal, navigate to the Security page.
  2. For the environment you plan to use, select the corresponding tab.
  3. In the Request section, click Add Security.
    The "Add certificate" dialog appears.
  4. For the "Certificate use" dropdown, select MTLS.
  5. In the "Certificate upload" box, drag and drop, or browse for the desired certificate. Add one certificate here. In total, a maximum of two certificates can share the same Common Name.
  6. Click Add Certificate.
    The "Add security" dialog closes. The added mTLS Certificate is listed.

Add your Digital Signature Certificate

If applicable, provide the Digital Signature Certificate to ensure the integrity and authenticity of the request:

  1. In the Payments Developer Portal, navigate to the Security page.
  2. For the environment you plan to use, select the corresponding tab.
  3. In the Request section, click Add Security.
    The "Add certificate" dialog appears.
  4. For the "Certificate use" dropdown, select Digital Signature.
  5. In the "Certificate upload" box, drag and drop, or browse for the desired certificate. Add up to two certificates here.
  6. Click Add Certificate.
    The "Add security" dialog closes. The added Digital Signature Certificate is listed.

Call a J.P. Morgan API

After you have added a client certificate(s), you can make a request to a J.P. Morgan API.

The following two sections describe making a call if you are not using a Digital Signature and making a call if you are using a Digital Signature.

Without a Digital Signature

If you are not using a Digital Signature, use the statement:

curl --request GET --url <API endpoint> --header "Content-Type: application/json" --cert <certificate file> -- key <private key> --data <JSON payload>

Update "Content-Type: " — Insert the content-type into the quoted variable. Our current APIs accept "Content-Type: text/xml" while newer APIs prefer the use of "Content-Type: application/json" but will continue to support "Content-Type: text/xml" for some time.

Update the angle bracketed variables as follows:

  • <API endpoint> — Replace with the endpoint for the API.
  • <certificate file> — Replace with your certificate name.
  • <private key> — Replace with your private key.
  • <JSON payload> — Replace with the  JSON corresponding to your API.

Make the API call.
Confirm by reviewing the response in the JSON.

With a Digital Signature

An API using a Digital Signature requires a signed JSON Web Signature (JWS) payload. A signed JWS payload is produced using your private key and JSON payload, and hashed using the RS256 algorithm.

Tip

RS256 is an asymmetric algorithm that uses a private key to sign the JWS.

You can generate a JWS payload in the request body by first converting the JSON payload that needs to be signed to a UTF8 encoded string and apply Base64-URL encoding.

Next, populate the JWS header with the alg parameter.

The following example code block (available in Java or JavaScript) retrieves the private key from a file, signs the data using the private key, and then generates the JWS with the signed payload.

Example Java code generate the JWS with the signed payload
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.io.IOException;
import org.apache.commons.io.IOUtils;

/* Retrieve the Private Key from a file */
public PrivateKey getPrivateKey(String privateKeyFileName) 
        throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
    byte[] keyBytes = IOUtils.toByteArray(getResource(privateKeyFileName).getInputStream());
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePrivate(spec);
}

/* Sign the data using the private key that is stored in keyFile path */
public byte[] signPayload(String encodedPayload, String keyFileName) 
        throws InvalidKeyException, Exception {
    Signature rsa = Signature.getInstance("SHA256withRSA");
    rsa.initSign(getPrivate(keyFileName));
    rsa.update(encodedPayload.getBytes());
    return rsa.sign();
}

/* Construct the JWS with the signed payload */
public void generateJWS(DigitalSignature sig) throws InvalidKeyException {
    String encodedHeader = encodeBase64URL(getHeader());
    String encodedBody = encodeBase64URL(getBody());
    String jws = encodedHeader.concat(".")
            .concat(encodedBody).concat(".")
            .concat(encodeBase64URL(signPayload(
                    encodedHeader.concat(".").concat(encodedBody),
                    getKeyFileName())));
}

Execute your code and copy the output.

Using the statement:

curl --request POST --url <API endpoint> --header "Content-Type: application/jose" --cert <certificate file> -- key <private key> --data <signed JWS payload>

Update "Content-Type: " — Insert the content-type into the quoted variable. Our current APIs accept "Content-Type: text/xml" while newer APIs prefer the use of "Content-Type: application/jose" but will continue to support "Content-Type: text/xml" for some time.

Update the angle bracketed variables as follows:

  • <API endpoint> — Replace with the endpoint for the API.
  • <certificate file> — Replace with your certificate name.
  • <private key> — Replace with your private key.
  • <signed JWS payload> — Replace with the output from the JWS script above.

Make the API call.
Confirm by reviewing the response in the JSON.