|
| 1 | +# Decrypt OpenID Connect encrypted ID tokens |
| 2 | + |
| 3 | +WSO2 Identity Server provides encrypted ID tokens to address security vulnerabilities in the production environment. |
| 4 | + |
| 5 | +- Unencrypted JWT ID tokens contain only two base64 encoded portions separated by a period (`.`). |
| 6 | + |
| 7 | + ```xml |
| 8 | + <header>.<body> |
| 9 | + ``` |
| 10 | + |
| 11 | + The following is an example where unencrypted ID tokens contain only two base64 encoded portions separated by a period (`.`). |
| 12 | + |
| 13 | + ```java |
| 14 | + eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhbGljZSIsImlzcyI6Imh0dHBzOlwvXC9jMmlkLmNvbSIsImlhdCI6MTQxNjE1ODU0MX0 |
| 15 | + ``` |
| 16 | + |
| 17 | +- Encrypted ID tokens contain five base64 encoded portions separated by a period (`.`). |
| 18 | + |
| 19 | + ```xml |
| 20 | + <header>.<Encrypted_Key>.<Initialization_Vector>.<Ciphertext>.<Authentication_Tag> |
| 21 | + ``` |
| 22 | + |
| 23 | + The following is an example where the encrypted ID token contains five base64 encoded portions separated by a period (`.`). |
| 24 | + |
| 25 | + ```java |
| 26 | + eyJ4NXQiOiJOVEF4Wm1NeE5ETXlaRGczTVRVMVpHTTBNekV6T0RKaFpXSTRORE5sWkRVMU9HRmtOakZpTVEiLCJraWQiOiJOVEF4Wm1NeE5ETXlaRGczTVRVMVpHTTBNekV6T0RKaFpXSTRORE5sWkRVMU9HRmtOakZpTVEiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBMV81In0.Zwp2xDvYER9lAo43QrYrcaKz-tPLFPYZb2s4RontDDVyvdo-seYl6II2C1Wb4cQhXdipcB_Qj093xvLrJyZXWxeavqYhryeuHi2jgcs59MfV1U9hMaKqqjVN1pcZYSrxDzn5leBF5bw7_YKaD_R6cFY8VtpVv5j_U8WohtyIjM7_n2CsZ55vY8MUHCAYxzXK9_s75e6Ug8L4MEqpgeoJGQzYCxFrBFgGyDMv1jadLwNl4Y3yLhv4RLtQMU5AM6nODI601UfYdrapObF3mpl_74H_YdRqT28LepGMtkEXbjeRgB-FiFGLvYlrK4wygczLBKrcviVyzyhrIrqz3TYV3g.Lf5lECzAdyAGgP8t.SHBUZoWkqwW_7u0GElrUqX1tewqRaUMWdGPHxpLRPmpVuc7FwQ27-kdsQ6O1_twhZ7uzjzZaEkatNhMxy9k10733-r4GT1lTGVqidKiBZq3mRQu7qJpcz7JWUroNFRLxhSoqpLpC8_tAhkohzG-mE42xdEh4tNDy3pBtAG0fe42WrLtWTuyg5lpmOYSppOc2Gb6LcDr4MmxFNPgoatF0edJSgO-CpFJQTcXn-22lU2g7o22x3RcBx9_KZH0At3g9y9uTuBncExOoBRK_ZweKOl0q76TaLiv5faXINW15xz9hILA.RGYIL7FaQqAIMPAiQdkOig |
| 27 | + ``` |
| 28 | + |
| 29 | +If you want to see the exact JSON values of the ID token, you have to decrypt it. |
| 30 | + |
| 31 | +The following is a simple Java program to decrypt the ID token using the default `wso2carbon.jks` keystore in WSO2 Identity Server. |
| 32 | + |
| 33 | +```java |
| 34 | +package org.wso2.sample; |
| 35 | + |
| 36 | +import com.nimbusds.jose.crypto.RSADecrypter; |
| 37 | +import com.nimbusds.jwt.EncryptedJWT; |
| 38 | + |
| 39 | +import java.io.InputStream; |
| 40 | +import java.security.KeyStore; |
| 41 | +import java.security.interfaces.RSAPrivateKey; |
| 42 | + |
| 43 | +public class DecryptIDToken { |
| 44 | + public static void main(String[] args) throws Exception { |
| 45 | + |
| 46 | + // Get keystore as a resource. |
| 47 | + InputStream file = ClassLoader.getSystemResourceAsStream("wso2carbon.jks"); |
| 48 | + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); |
| 49 | + keystore.load(file, "wso2carbon".toCharArray()); |
| 50 | + |
| 51 | + String alias = "wso2carbon"; |
| 52 | + |
| 53 | + // Get the private key. Password for the key store is 'wso2carbon'. |
| 54 | + RSAPrivateKey privateKey = (RSAPrivateKey) keystore.getKey(alias, "wso2carbon".toCharArray()); |
| 55 | + |
| 56 | + // Enter encrypted JWT String here. |
| 57 | + String encryptedJWTString = "eyJ4NXQiOiJOVEF4Wm1NeE5ETXlaRGczTVRVMVpHTTBNekV6T0RKaFpXSTRORE5sWkRVMU9HRmtOakZp" + |
| 58 | + "TVEiLCJraWQiOiJOVEF4Wm1NeE5ETXlaRGczTVRVMVpHTTBNekV6T0RKaFpXSTRORE5sWkRVMU9HRmtOakZpTVEiLCJlbmMiOiJ" + |
| 59 | + "BMjU2R0NNIiwiYWxnIjoiUlNBMV81In0.Zwp2xDvYER9lAo43QrYrcaKz-tPLFPYZb2s4RontDDVyvdo-seYl6II2C1Wb4cQhXd" + |
| 60 | + "ipcB_Qj093xvLrJyZXWxeavqYhryeuHi2jgcs59MfV1U9hMaKqqjVN1pcZYSrxDzn5leBF5bw7_YKaD_R6cFY8VtpVv5j_U8Woh" + |
| 61 | + "tyIjM7_n2CsZ55vY8MUHCAYxzXK9_s75e6Ug8L4MEqpgeoJGQzYCxFrBFgGyDMv1jadLwNl4Y3yLhv4RLtQMU5AM6nODI601UfY" + |
| 62 | + "drapObF3mpl_74H_YdRqT28LepGMtkEXbjeRgB-FiFGLvYlrK4wygczLBKrcviVyzyhrIrqz3TYV3g.Lf5lECzAdyAGgP8t.SHB" + |
| 63 | + "UZoWkqwW_7u0GElrUqX1tewqRaUMWdGPHxpLRPmpVuc7FwQ27-kdsQ6O1_twhZ7uzjzZaEkatNhMxy9k10733-r4GT1lTGVqidK" + |
| 64 | + "iBZq3mRQu7qJpcz7JWUroNFRLxhSoqpLpC8_tAhkohzG-mE42xdEh4tNDy3pBtAG0fe42WrLtWTuyg5lpmOYSppOc2Gb6LcDr4M" + |
| 65 | + "mxFNPgoatF0edJSgO-CpFJQTcXn-22lU2g7o22x3RcBx9_KZH0At3g9y9uTuBncExOoBRK_ZweKOl0q76TaLiv5faXINW15xz9h" + |
| 66 | + "ILA.RGYIL7FaQqAIMPAiQdkOig"; |
| 67 | + |
| 68 | + EncryptedJWT jwt = EncryptedJWT.parse(encryptedJWTString); |
| 69 | + |
| 70 | + // Create a decrypter with the specified private RSA key. |
| 71 | + RSADecrypter decrypter = new RSADecrypter(privateKey); |
| 72 | + |
| 73 | + jwt.decrypt(decrypter); |
| 74 | + |
| 75 | + // Printing decrypted id token header. |
| 76 | + System.out.println("ID token header: " + jwt.getHeader().toJSONObject()); |
| 77 | + |
| 78 | + // Printing decrypted id token header. |
| 79 | + System.out.println("ID token claims: " + jwt.getJWTClaimsSet().toJSONObject()); |
| 80 | + } |
| 81 | +} |
| 82 | +``` |
| 83 | + |
| 84 | +When encrypted ID tokens are produced, two encryption processes happen. First, a random Content Encryption Key (CEK) is generated. Then the payload is encrypted using this CEK and a symmetric encryption algorithm, which is called the encryption method. Then the CEK is encrypted again using the public key of the client and an asymmetric encryption algorithm, which is called the encryption algorithm. |
| 85 | + |
| 86 | +You can read more about these concepts in the [RFC 7516 specification](https://tools.ietf.org/html/rfc7516). |
| 87 | + |
| 88 | +You can configure the default values of the encryption method and encryption algorithm by making changes to the `<IS_HOME>/repository/conf/deployment.toml` file. |
| 89 | + |
| 90 | +```toml |
| 91 | +[oauth.oidc.id_token] |
| 92 | +supported_encryption_algorithms=["RSA1_5","RSA-OAEP"] |
| 93 | +supported_encryption_methods=["A128GCM","A192GCM","A256GCM","A128CBC-HS256","A128CBC+HS256"] |
| 94 | +``` |
| 95 | + |
| 96 | +For encryption algorithm, WSO2 Identity Server currently supports the following algorithms: |
| 97 | + |
| 98 | +- RSA1_5 |
| 99 | +- RSA-OAEP |
| 100 | + |
| 101 | +For encryption method, WSO2 Identity Server currently supports the following algorithms: |
| 102 | + |
| 103 | +- A128GCM |
| 104 | +- A192GCM |
| 105 | +- A256GCM |
| 106 | +- A128CBC-HS256 |
| 107 | +- A128CBC+HS256 |
| 108 | + |
| 109 | +!!! note |
| 110 | + The default keystore shipped with WSO2 products is `wso2carbon.jks`. The password for the keystore is `wso2carbon` and the certificate alias is also `wso2carbon`. In a production environment, we recommend that you change these values. |
| 111 | + |
| 112 | +!!! info "Related topics" |
| 113 | + - [Concept: ID Token]({{base_path}}/references/concepts/authentication/id-token/) |
| 114 | + - [Guide: Encrypt ID tokens]({{base_path}}/guides/authentication/oidc/oidc-token-encryption/) |
0 commit comments