Thursday, May 21, 2026

OIC - User Access Provisioning & Revocation Between CORS and OPC

Working...

Introduction

In enterprise environments, user access management between external systems and Oracle platforms is a common integration requirement. In this use case, we implemented an automated solution using Oracle Integration Cloud to provision and revoke user access between CORS and OPC.

The integration supports two major flows:

OPC to CORS Sync Flow

Scheduled integration

Extracts users, departments, and groups from OPC

Generates files and sends them to SFTP for CORS pickup

CORS to OPC Access Management Flow

REST-based integration

Receives user/group/department details from CORS

Creates users and assigns access in OPC

Returns failed group assignment responses

This architecture helped automate access governance, reduce manual intervention, and improve synchronization accuracy across systems.

Flow 1 – OPC to CORS Synchronization

Requirement

CORS requires periodic synchronization data from OPC containing:

User details

Department mappings

Department-group mappings

Department-group-user mappings

The files need to be generated automatically and placed in an SFTP location for CORS consumption.

Solution Design

We implemented a Scheduled Integration in Oracle Integration Cloud.

High-Level Steps

  1. Scheduler triggers the integration periodically
  2. OIC calls OPC APIs and retrieves authentication token
  3. Fetches: 
    • Departments 
    • Department and group mappings Department-group-user mappings
  4. Generates 3 outbound files
  5. Uploads files to OIC SFTP location
  6. CORS picks up the files from SFTP

Integration Flow

Step 1 – Scheduler Trigger

A scheduled orchestration integration was configured to run at defined intervals.

Example:

Every 1 hour

Daily batch sync

Based on business requirement

Step 2 – OPC Authentication

The integration first invokes OPC authentication APIs to retrieve access tokens.

This token is then used for all subsequent OPC REST API calls.

Step 3 – Fetch Department and Group Details

Multiple REST calls were made to OPC APIs:

APIs Used

Get Departments

Get Groups by Department

Get Users by Group and Department

The data was staged and transformed inside OIC.

Step 4 – Generate Output Files

Three files were generated:

File

Description

Department File

Contains department details

Department-Group File

Contains group mapping information

Department-Group-User File

Contains user assignment details

Files were generated in CSV format.

Step 5 – Upload Files to SFTP

Using OIC FTP/SFTP Adapter, the files were uploaded to the designated SFTP location.

CORS system then picked up the files for downstream processing.

Benefits of Flow 1

Fully automated synchronization

No manual file preparation

Centralized access data management

Reduced synchronization errors

Easy scalability for future enhancements

Flow 2 – CORS to OPC User Provisioning

Requirement

CORS sends user access requests to OIC.

The integration must:

  1. Create users in OPC
  2. Assign department access
  3. Add users to groups
  4. Return failure responses for unsuccessful group assignments

Solution Design

We exposed a REST API from Oracle Integration Cloud for CORS consumption.

The design was modularized using:

One Main Integration

Multiple Child Integrations

This improved reusability and maintainability.

Architecture Overview

Main Integration

The main orchestration integration performs:

Receives REST payload from CORS

Validates incoming request

Calls child integrations

Consolidates responses

Sends failure details back to CORS

Child Integration 1 – User Creation

This integration handles:

User creation in OPC

User validation

Existing user checks

Error handling

Key Features

Reusable integration

Can be invoked independently

Centralized user onboarding logic

Child Integration 2 – Group and Department Assignment

This integration performs:

Group assignment

Department mapping

Role association

If any group assignment fails, the integration captures the failure details.

Failure Handling Mechanism

One important business requirement was to return failed group assignments back to CORS.

Example Failure Scenarios

Group does not exist

Invalid department

User already assigned

OPC API failure

The integration collected all failed records and prepared a consolidated response.

Sample Response Structure

JSON

{

  "status": "PARTIAL_SUCCESS",

  "failedGroups": [

    {

      "user": "ABC123",

      "group": "Finance_Admin",

      "reason": "Group not found"

    }

  ]

}

Key Advantages of the Solution

  • Modular Design
  • Using child integrations improved:
  • Reusability
  • Maintainability
  • Independent testing
  • Better Error Tracking
  • Detailed failure responses helped CORS quickly identify provisioning issues.
  • Scalable Architecture
  • The solution can easily support:
  • Additional departments
  • More user attributes
  • Future access models

Conclusion

This integration solution using Oracle Integration Cloud enabled seamless synchronization and automated user access management between CORS and OPC.

The implementation provided:

  • Automated provisioning and revocation
  • Secure file-based synchronization
  • REST-based onboarding
  • Modular child integration architecture
  • Detailed failure reporting
  • This approach significantly reduced manual effort while improving access governance and operational efficiency across systems.

Sunday, May 10, 2026

OIC - OCI Java function code for RSA Encryption and Decryption

Function Java code:

package com.test.fn;

import java.security.*;

import java.security.spec.*;

import java.util.Base64;

import javax.crypto.Cipher;

import java.util.logging.*;

public class RSAEncryptDecrypt {

    private static final Logger logger = Logger.getLogger(RSAEncryptDecrypt.class.getName());

  public static class Input {

        public String message;

        public String secretKeyBase64;

        public String rsaMode;

        public String actionType; // ENCRYPT or DECRYPT

    }

    public static class Result {

        public String message;

        public String executionInfo;

    }

    public Result handleRequest(Input input) throws Exception {

        logger.log(Level.INFO, "OIC - message:", input.message);

        logger.log(Level.INFO, "OIC - secretKeyBase64:", input.secretKeyBase64);

        logger.log(Level.INFO, "OIC - rsaMode:", input.rsaMode);

        logger.log(Level.INFO, "OIC - actionType:", input.actionType);

        Result result = null;

        if ("DECRYPT".equals(input.actionType)) {

            result = decryptMyMessage(input);

        } else if ("ENCRYPT".equals(input.actionType)) {

            result = encryptMyMessage(input);

        } else {

            result = new Result();

            result.executionInfo = "ERROR: No proper action found , possible value "

                    + "is ENCRYPT or DECRYPT , recieved value:"

                    + input.actionType;

        }

        return result;

    }

// Method to encrypt plaintext using the RSA public key

 public Result encryptMyMessage(Input input) throws Exception {

     Result result = new Result();

     try {

         PublicKey publicKey = loadPublicKey(input.secretKeyBase64);

         Cipher cipher = Cipher.getInstance(input.rsaMode); // RSA encryption scheme

         cipher.init(Cipher.ENCRYPT_MODE, publicKey);

         byte[] encryptedBytes =                cipher.doFinal(input.message.getBytes());

         result.message =                 Base64.getEncoder().encodeToString(encryptedBytes);

         result.executionInfo = "SUCCESS";

     } catch (Exception e) {

         result.executionInfo = e.getMessage();

         logger.log(Level.INFO, "Error Details:", e.getMessage());

     }

     return result; // return as Base64 string

 }

 public Result decryptMyMessage(Input input) throws Exception {

     Result result = new Result();

     try {

         Cipher decryptCipher =

                 Cipher.getInstance(input.rsaMode);

         PrivateKey privateKey =                getPrivateKeyFromString(input.secretKeyBase64);         decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);

         byte[] decryptedBytes =

                 decryptCipher.doFinal(                       Base64.getDecoder().decode(input.message));

         String myDecryptedMsg =

                 new String(decryptedBytes, "UTF-8");

         result.message = myDecryptedMsg;

         result.executionInfo = "SUCCESS";

     } catch (Exception e) {

         result.executionInfo = e.getMessage();

         logger.log(Level.INFO, "Error Details:", e.getMessage());

     }

     return result; // return as Base64 string

 }

// Converts a Base64-encoded public key string to PublicKey object

 public static PublicKey loadPublicKey(String base64PublicKey) throws Exception {

     byte[] keyBytes =            Base64.getDecoder().decode(base64PublicKey);

     X509EncodedKeySpec spec =

             new X509EncodedKeySpec(keyBytes);

     KeyFactory keyFactory =

             KeyFactory.getInstance("RSA");

     return keyFactory.generatePublic(spec);

 }

 // Convert Base64 string to PrivateKey

 public static PrivateKey getPrivateKeyFromString(String base64PrivateKey)

         throws Exception {

     byte[] keyBytes =            Base64.getDecoder().decode(base64PrivateKey);

     PKCS8EncodedKeySpec spec =

             new PKCS8EncodedKeySpec(keyBytes);

     KeyFactory factory =

             KeyFactory.getInstance("RSA");

     return factory.generatePrivate(spec);

 }

}

Java code Screenshots:





Friday, May 8, 2026

OIC - Improving OIC Performance – Avoid Large Payloads in String Variables | String Size Limit Warning Message

While working with large payloads in Oracle Integration Cloud (OIC), especially from BIP report responses, many developers store the complete response inside a string variable for later processing or logging.

This works initially, but when the payload becomes too large, OIC may start showing a warning like:

“String size limit”



This is commonly seen when the string exceeds around 10,000 characters (10K).

OIC Server limit:

If the size of a string variable exceeds 10,000 characters, a warning message is shown in the activity stream. Oracle Integration does not currently impose a limit on the size of string variables. However, this may be subject to change in the future, which could result in a flow execution failing when the limit is exceeded.

Common Scenario

We had a use case where:

OIC was calling a BIP Report

The report response contained a very large XML/Base64 payload

Entire response was stored in a string variable

Integration completed successfully, but OIC generated a warning notification

Typical warning behavior:

Integration still succeeds

Activity stream shows warning

OIC dashboard displays alert notification

Performance may degrade due to heavy in-memory string handling

Why This Happens

OIC internally maintains limits for string handling in memory.

When a very large payload is stored in:

Assign activity variables

String variables

Logger messages

Tracking fields

OIC raises a String Size Limit Warning.

This does not always fail the integration immediately, but it can:

Increase memory usage

Slow down execution

Create unnecessary activity stream overhead

Impact overall integration performance

Real Impact on Performance

Large string variables can cause:

1. Increased Memory Consumption

Huge payloads remain loaded in memory during runtime.

2. Slower Assign Activities

Assigning massive strings repeatedly increases processing time.

3. Activity Stream Overhead

OIC tries to maintain activity and debug information.

4. Payload Serialization Cost

Large string conversion operations impact performance.

5. Difficult Debugging

Very large payload logs become hard to analyze.

Recommended Resolution

1. Avoid Storing Full Payload in String Variables

Instead of:

Storing complete BIP response

Storing entire Base64 output

Keeping full XML/JSON in string variables

Store only:

Required nodes

Specific fields

IDs/status values

2. Use Stage File for Large Content

For large payload processing:

Write payload into Stage File

Process file stream-wise

Avoid keeping everything in memory

This is the best approach for:

Large XML

CSV

Base64 documents

Huge BIP outputs

3. Read Only Required Data

Instead of mapping the complete payload:

Extract only needed elements using:

XPath

JSON path

Stage File Read

Example:

Employee Number

Report Status

File Name

Document ID

Avoid unnecessary full payload assignments.

4. Avoid Logging Full Payloads

Do not log:

Entire XML

Complete Base64

Large JSON responses

Instead log:

Record count

Transaction ID

Small status messages

5. Use Attachments/File References When Possible

For document-heavy integrations:

Pass file references

Use attachments

Use opaque/binary handling

Instead of converting everything into strings.

Best Practice Architecture

Recommended flow:

Call BIP Report

Receive large payload

Store in Stage File / Attachment

Read only required fields

Pass file reference downstream

Avoid huge string variables

Key Takeaway

If OIC shows: String Size Limit Warning. it usually means: 

Integration processed a very large string payload

OIC memory threshold warning was triggered

Integration may still succeed

But performance optimization is needed

Reference:

https://community.oracle.com/customerconnect/discussion/926935/oic-string-size-limit-alert?utm_source=chatgpt.com


Thursday, May 7, 2026

OIC - Handling dynamic JSON Payloads in OIC Using Binary JSON Media Type

 In Oracle Integration Cloud (OIC), there are scenarios where the source system sends dynamic or variable JSON payloads through a REST service. Since the structure may change frequently, creating strict schemas becomes difficult.

In our requirement, the incoming JSON payload needs to be passed to the target Communication Cloud service as escaped JSON, while also reading only a few required fields from the payload for validations or processing.

Requirement

Expose a REST API in OIC.

Source system can send any type of JSON structure.

Need to avoid strict request schema dependency.

Read only required fields from the payload.

Pass the complete original JSON payload to Communication Cloud service as escaped JSON.

Solution Approach

1. Configure REST Trigger with Binary JSON Media Type

While creating the REST trigger:

Select Binary as the request payload type.

Set media type as:

Plain text

application/json

This allows OIC to accept any JSON structure dynamically without schema validation.


Benefit

No dependency on fixed JSON schema.

Supports variable or changing payload structures.

Prevents failures due to unexpected fields.

2. Read Required Fields Using Stage File Action

Since the payload is received as binary content:

Use Stage File → Read Entire File

Read the incoming payload as JSON.

From the Stage File schema, extract only the required fields needed for processing.

Example:

JSON

{

  "employeeId": "1001",

  "status": "ACTIVE",

  "dynamicData": {

      ...

  }

}

You may read only: employeeId , status without validating the complete payload structure.



3. Preserve Original JSON Payload

The key advantage of this approach is:

The original payload remains unchanged.

No need to reconstruct JSON again in mapper.

Entire payload can directly be forwarded to downstream systems.

4. Pass Complete Payload to Communication Cloud

The target Communication Cloud service expects escaped JSON.

Since the original payload is already preserved:

Map the complete payload directly to target request.

Use escaped JSON/string format as required by Communication Cloud API.

Example target payload:

JSON

{

  "payload": "{\"employeeId\":\"1001\",\"status\":\"ACTIVE\"}"

}


Architecture Flow

Plain text

  • Source System

      ↓

OIC REST Trigger

(Binary JSON Media Type)

      ↓

Stage File Read

(Read only required fields)

      ↓

Map Original Payload

      ↓

Communication Cloud REST Service

(Escaped JSON)

Advantages of This Approach

  • Supports dynamic JSON structures.
  • No schema maintenance effort.
  • Avoids trigger regeneration issues.
  • Easy handling of changing payloads.
  • Efficient for pass-through integrations.
  • Only required fields are parsed.

Conclusion

Using Binary JSON media type in OIC REST triggers is an effective solution when handling variable JSON payloads. By combining it with Stage File read operations, we can selectively access required fields while still forwarding the complete original payload to downstream systems like Communication Cloud without rebuilding the JSON structure.

Tuesday, May 5, 2026

OIC - Handling Unknown Record Types in OIC (Header / Detail / Footer Detection) | How to validate a string in yyyymmdd is in date format?

📌 Problem Statement

In one of our Oracle Integration Cloud (OIC) file-based integrations, the source file structure was unclear.

We were receiving records, but no explicit identifier was present to distinguish:

Header

Detail

Footer

However, we observed one consistent pattern: 👉 Detail records always contain a date in YYYYMMDD format at a fixed position.

💡 Solution Approach

We used this date pattern as a validation key to identify detail records.

✔️ Logic:

Extract substring from the record (specific position where date exists)

Convert it into proper date format (YYYY-MM-DD)

Compare with original substring

Count matching records

If count = 0 → No detail record → Fail validation

🛠️ OIC Implementation

Step 1: Extract Date from Record

Assume date starts at position 19 in the string:

Xpath

substring(ns30:Data, 19, 8)

Step 2: Convert to Proper Date Format

Xpath

concat(

  substring(ns30:Data, 19, 4), "-",

  substring(ns30:Data, 23, 2), "-",

  substring(ns30:Data, 25, 2)

)

Step 3: Validate Date Format

Xpath

xp20:format-dateTime(

  concat(

    substring(ns30:Data, 19, 4), "-",

    substring(ns30:Data, 23, 2), "-",

    substring(ns30:Data, 25, 2)

  ),

  "[Y0001][M01][D01]"

)

Step 4: Compare with Original Value

Xpath

xp20:format-dateTime(...) = substring(ns30:Data, 19, 8)

👉 If TRUE → Valid date → Detail record

Step 5: Count Detail Records

Xpath

count(

  $ReadRawFile/nsmpr0:ReadResponse/ns30:RawFileRowSet/ns30:RawFileRow[

    xp20:format-dateTime(

      concat(

        substring(ns30:Data, 19, 4), "-",

        substring(ns30:Data, 23, 2), "-",

        substring(ns30:Data, 25, 2)

      ),

      "[Y0001][M01][D01]"

    ) = substring(ns30:Data, 19, 8)

  ]

)

🚨 Final Validation Condition

Xpath

count(...) = 0

Meaning:

✅ If count > 0 → Detail records exist → Proceed

❌ If count = 0 → No detail records → Fail Integration

🎯 Key Benefits

No dependency on explicit record type indicators

Works with inconsistent file formats

Lightweight validation using XPath

Prevents downstream processing errors

⚡ Pro Tip

If date position may vary or data is dirty:

Use normalize-space() before substring

Add additional checks (length = 8, numeric check)

🧾 Conclusion

When file structure is ambiguous, pattern-based validation (like date detection) is a powerful technique in OIC.

This approach ensures that only valid detail records are processed, improving reliability and 

Wednesday, April 29, 2026

OIC - RSA sign and verify java code for OCI Function

Java code:

package com.test.fn;

import java.security.*;
import java.security.spec.*;
import java.util.Base64;
import java.util.logging.*;
import java.security.MessageDigest;

public class RSASignVerify {

    private static final Logger logger =
        Logger.getLogger(RSASignVerify.class.getName());

    public static class Input {
        public String message;
        public String signatureBase64;
        public String publicKeyBase64;
        public String privateKeyBase64;
        public String hashType;
        public String actionType; //SIGN or VERIFY
        public String messageType; // BASE64 or TEXT or MESSAGE_TO_DIGEST
    }

    public static class Result {
        public boolean verifyResult;
        public String signatureBase64;
        public String executionInfo;
    }
/**
 * Verifies an RSA signature.
 *
 * @param Input
 * The original data that was signed.
 * signatureBase64 The signature in Base64 encoding.
 * publicKeyBase64 The RSA public key in Base64 encoding (X.509 format).
 * HashType Hashing value to Initialize the Signature object for verification, SHA256withRSA.
 *
 * @return true if the signature is valid, false otherwise.
 * @throws Exception on errors during verification.
 */
public Result verifyMessage(Input input) throws Exception {
    Result result = new Result();
    try {

        // Decode the public key
        byte[] publicKeyBytes = Base64.getDecoder().decode(input.publicKeyBase64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);

        // Decode the signature
        byte[] signatureBytes = Base64.getDecoder().decode(input.signatureBase64);

        // Initialize the Signature object for verification with SHA256withRSA
        Signature signature = Signature.getInstance(input.hashType);
        signature.initVerify(publicKey);
if("BASE64".equals(input.messageType)){
    byte [] messageBytes = Base64.getDecoder().decode(input.message);
    signature.update(messageBytes);
}else if ("MESSAGE_TO_DIGEST".equals(input.messageType)){
    signature.update(getDigestBytes(input.message));
}else{
    signature.update(input.message.getBytes("UTF-8"));
}

// Verify the signature
result.verifyResult = signature.verify(signatureBytes);
result.executionInfo = "SUCCESS";

} catch(Exception e) {
    result.verifyResult = false;
    result.executionInfo = e.getMessage();
    System.out.println("Error Details:" + e.getMessage());
}
return result;
}
public Result signMessage(Input input) throws Exception {
    Result result = new Result();
    try {

        // Decode the private key
        byte[] keyBytes = Base64.getDecoder().decode(input.privateKeyBase64);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey=keyFactory.generatePrivate(spec);

        // Initialize the Signature object for verification with SHA256withRSA
        Signature signature = Signature.getInstance(input.hashType);
        signature.initSign(privateKey);

        //sign message
        if("BASE64".equals(input.messageType)){
            byte [] messageBytes = Base64.getDecoder().decode(input.message);
            signature.update(messageBytes);
        }else{
            signature.update(input.message.getBytes("UTF-8"));
        }

        byte[] signedBytes = signature.sign();

        //generate signature
        result.signatureBase64 = Base64.getEncoder().encodeToString(signedBytes);
        result.executionInfo = "SUCCESS";

} catch (Exception e) {

result.executionInfo = e.getMessage();

System.out.println("Error Details:" + e.getMessage());

}

return result;

}

//For FPS

public static byte[] getDigestBytes (String message) throws Exception {

MessageDigest digest = MessageDigest.getInstance("SHA-256");

digest.update (message.getBytes());

byte[] message_digest = digest.digest();

return message_digest;
}

public Result handleRequest (Input input) throws Exception {

logger.log(Level.INFO, "OIC message:", input.message);

logger.log (Level.INFO, "OIC actionType:", input.actionType);

Result result = null;

if ("SIGN".equals(input.actionType)) {

result = signMessage (input);

} else if ("VERIFY".equals(input.actionType)) {

result = verifyMessage(input);

} else {

result = new Result();

result.executionInfo = "ERROR: No proper action found, possible value "

+ "is VERIFY or SIGN recieved value:"

+ input.actionType;
}

return result;

}}

For online testing we can use below code:
public static void main(String[] args) {

    Input input = new Input();
    input.message =  "base64 encrypted message";

    input.actionType = "VERIFY";
    input.messageType = "BASE64";
    input.hashType = "SHA256withRSA";
    input.signatureBase64 = "Base64 encoded signature";

    input.publicKeyBase64 =   "Public key";

    try {
        RSASignVerify service = new RSASignVerify();
        Result result = service.handleRequest(input);

        System.out.println(result.executionInfo);

        System.out.println("Signature: " + result.signatureBase64);
        System.out.println("Verify Result: " + result.verifyResult);
        System.out.println("Execution Info: " + result.executionInfo);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


Code screenshots:







Sunday, April 26, 2026

OIC - OCI function Java code to encrypt and decrypt using AES key

Please find the below working code:

Working Function code:

package com.test .fn;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import java.util.Base64;

import java.util.logging.*;

import java.security.SecureRandom;

public class AESEncryptDecrypt {

    private static final Logger logger = Logger.getLogger(AESEncryptDecrypt.class.getName());

    public static class Input {

        public String message;

        public String secretKeyBase64;

        public String ivBase64;

        public String aesMode; // AES/CBC/PKCS5Padding or AES/ECB/PKCS5Padding

        public String actionType; //ENCRYPT or DECRYPT

    }

    public static class Result {

        public String message;

        public String salt;

        public String wechataeskey;

        public String executionInfo;

    }

    public Result handleRequest(Input input) {

        logger.log(Level.INFO, "OIC - message:", input.message);

        logger.log(Level.INFO, "OIC - secretKeyBase64:", input.secretKeyBase64);

        logger.log(Level.INFO, "OIC - ivBase64", input.ivBase64);

        logger.log(Level.INFO, "OIC - aesMode:", input.aesMode);

        logger.log(Level.INFO, "OIC - actionType:", input.actionType);

        Result result = null;

if ("DECRYPT".equals(input.actionType)) {

    result = decryptMyMessage(input);

} else if ("ENCRYPT".equals(input.actionType)) {

    result = encryptMyMessage(input);

} else {

    result = new Result();

    result.executionInfo = "ERROR: No proper action found , possible value is ENCRYPT or DECRYPT , recieved value:" + input.actionType;

}

return result;

}

// Generate random 16-byte IV for AES/CBC

public static IvParameterSpec generateIV() {

    byte[] iv = new byte[16]; // 128-bit IV

    new SecureRandom().nextBytes(iv);

    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

    return ivParameterSpec;

}

public Result encryptMyMessage(Input input) {

    Result result = new Result();

    try {

        byte[] decodedKey = null;

        if (input.secretKeyBase64 == null) {

            // Generate 16-digit random numeric string

            String keyString = generateRandomDigits(16);

            //System.out.println("Generated 16-digit AES key: " + keyString);

            // Convert to byte array (each digit becomes 1 byte, 16 bytes total = 128 bits)

            result.wechataeskey = keyString;

            decodedKey = keyString.getBytes("UTF-8");

        } else {

            // Decode the base64 encoded string

            decodedKey = Base64.getDecoder().decode(input.secretKeyBase64);

        }

byte[] messageBytes = input.message.getBytes("UTF-8");

// Create a SecretKeySpec for the AES key

SecretKeySpec secretKeySpec = new SecretKeySpec(decodedKey, "AES");

// Create a Cipher instance for AES

Cipher cipher = Cipher.getInstance(input.aesMode);

if (input.aesMode.contains("CBC")) {

    //AES/CBC/PKCS5Padding required IV

    IvParameterSpec ivParameterSpec = generateIV();

    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

    result.salt = Base64.getEncoder().encodeToString(ivParameterSpec.getIV());

} else {

    //AES/ECB/PKCS5Padding do not require IV

    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

}

// Decrypt the message

byte[] originalBytes = cipher.doFinal(messageBytes);

String encodedString = Base64.getEncoder().encodeToString(originalBytes);

result.message = encodedString;

//String originalMessage = =new String(originalBytes);

result.executionInfo = "SUCCESS";

} catch(Exception e) {

    result.executionInfo = e.getMessage();

    logger.log(Level.INFO, "Error Details:", e.getMessage());

}

return result;

}

public Result decryptMyMessage(Input input) {

    Result result = new Result();

    generateIV();

    try {

        // Decode the base64 encoded string

        byte[] decodedKey = Base64.getDecoder().decode(input.secretKeyBase64);

        byte[] encryptedBytes = Base64.getDecoder().decode(input.message);

        // Create a SecretKeySpec for the AES key

        SecretKeySpec secretKeySpec = new SecretKeySpec(decodedKey, "AES");

        // Create a Cipher instance for AES

        Cipher cipher = Cipher.getInstance(input.aesMode);

        if (input.aesMode.contains("CBC")) {

            //AES/CBC/PKCS5Padding required IV

            byte[] decodedIV = Base64.getDecoder().decode(input.ivBase64);

            IvParameterSpec ivParameterSpec = new IvParameterSpec(decodedIV);

            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

        } else {

            //AES/ECB/PKCS5Padding do not require IV

            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);

        }

        // Decrypt the message

        byte[] originalBytes = cipher.doFinal(encryptedBytes);

        String encodedString = Base64.getEncoder().encodeToString(originalBytes);

        result.message = encodedString;

        //String originalMessage = =new String(originalBytes);

        result.executionInfo = "SUCCESS";

    } catch(Exception e) {

        result.executionInfo = e.getMessage();

        logger.log(Level.INFO, "Error Details:", e.getMessage());

    }

    return result;

}

// Wechat, Generate a random string of digits for AES Key

public static String generateRandomDigits(int length) {

    SecureRandom random = new SecureRandom();

    StringBuilder sb = new StringBuilder(length);

    for (int i = 0; i < length; i++) {

        sb.append(random.nextInt(10)); // 0-9

    }

    return sb.toString();

}

public static void main(String[] args) {

    AESEncryptDecrypt service = new AESEncryptDecrypt();

    Input input = new Input();

    input.message = "put encrypted cyper message";

    // Base64 for "1234567890123456"

    input.secretKeyBase64 = "Put base64 encoded secret key";

    input.ivBase64 = "base63 encode salt ot IV";

    input.aesMode = "AES/CBC/PKCS5Padding";

    input.actionType = "DECRYPT";

    Result result = service.handleRequest(input);

    // Print output

    System.out.println("=== RESULT ===");

    System.out.println("Message: " + result.message);

    System.out.println("Salt: " + result.salt);

    System.out.println("WeChat AES Key: " + result.wechataeskey);

    System.out.println("Execution Info: " + result.executionInfo);

}

}

Screenshots:






Test online tool :

https://www.onlinegdb.com/online_java_compiler#



Featured Post

OPC vs Unifier – Simple Understanding

OPC vs Unifier – Simple Understanding Oracle Primavera Cloud (OPC) is mainly used for project execution and scheduling. It helps organizati...