soalicious
Wednesday, April 29, 2026
OIC - RSA sign and verify java code for OCI Function
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#
OIC - Secure Payload Handling in OIC using OCI Vault & Functions (AES + RSA) | Message level encryprion/decryption and signing/verification
Work in progress...
Overview
This blog covers a secure and scalable design pattern in Oracle Integration Cloud (OIC) where:
- Incoming payload is AES encrypted and RSA signed
- Keys are fetched from OCI Vault
- Cryptographic operations are handled via OCI Functions
- Response is encrypted and signed if required before sending back
Architecture
Source
↓ (AES Encrypted + RSA Signed)
Main Integration
↓
Crypto Integration
→ Fetch keys from OCI Vault
→ Call Function (AES Decrypt)
→ Call Function (RSA Verify)
↓
Main Integration
→ Call Target
← Response
↓
Crypto Integration
→ Call Function (AES Encrypt)
→ Call Function ( RSA Signed) optional
↓
Source (Encrypted and signed Response)
OCI Functions:
- Function 1: AES Encrypt/Decrypt
- Function 2: RSA Sign/Verify
Scenarios:
For java function code , use below link:
https://soalicious.blogspot.com/2026/04/oic-oci-function-code-to-encrypt-and.html
End-to-End Flow:
Step 1: Receive Request (Main Integration)
- Expose REST API
- Input contains:
- Encrypted payload (Base64)
- Signature
- Salt or IV
➡️ Call Crypto Integration for processing
Step 2: Crypto Processing Integrations
This integration acts as a central reusable crypto layer.
2.1 Fetch Keys from OCI Vault
- Retrieve:
- AES Secret Key
- RSA Private/Public Keys
- Use secure REST call / OCI SDK
Ensures no key is hardcoded in OIC
2.2 Call OCI Function – Decrypt
- Pass encrypted payload + key reference
- Function performs:
- Base64 decode
- AES decryption
Returns: Plain payload
2.3 Call OCI Function – RSA Verify
- Pass payload + signature + public key
- Function validates signature
Condition:
- Valid → proceed
- Invalid → throw fault
Step 3: Return Decrypted Data to Main Integration
- Crypto Integration sends verified plain payload back
Step 4: Business Processing (Main Integration - 1)
- Transform data
- Call target system
- Receive response
Step 5: Encrypt Response
Main Integration again calls Crypto Integration (2)
5.1 Call OCI Function – AES Encrypt
- Encrypt response payload
- Base64 encode
No RSA signing required for response
Step 6: Send Response
- Return encrypted response to source system
Conclusion
This approach provides a clean, secure, and enterprise-ready pattern in OIC by combining:
- OCI Vault for secure key management
- OCI Functions for cryptographic operations
- Reusable integrations for maintainability
A perfect design for handling sensitive real-time integrations at scale.
Thursday, April 23, 2026
OIC File Handling – Removing .pgp and Preserving .csv (Dynamic File Name Logic) | use of ast-index-within-string() function
๐ Problem Statement
In Oracle Integration Cloud (OIC), while working with Stage File, we often receive source files like:
a.b.c.csv.pgp ๐ (encrypted file)
a.b.c.csv ๐ (plain file)
๐ฏ Requirement
If file = a.b.c.csv.pgp → Target should be a.b.c.csv
If file = a.b.c.csv → Keep as a.b.c.csv
⚠️ Challenge
Handling multiple dots (.) in file names:
Simple logic may break
Functions like last-index-of() (or OIC equivalent) may not always behave as expected in mapper
✅ Approach 1: Nested substring-before/after (Working & Stable).
๐ป Code Snippet
XML
fn:concat(
fn:substring-before($FileName, '.'),
'.',
fn:substring-before(fn:substring-after($FileName, '.'), '.'),
'.',
fn:substring-before(fn:substring-after(fn:substring-after($FileName, '.'), '.'), '.'),
'.csv'
)
✔️ Behavior
Extracts each part between dots
Reconstructs filename ending with .csv
๐ Advantages
Works consistently in OIC mapper
No dependency on special functions
๐ Disadvantages
Not dynamic (hardcoded for 3 segments like a.b.c)
Breaks if file structure changes (e.g., a.b.c.d.csv.pgp)
⚡ Approach 2: Using oraext:last-index-within-string (Dynamic but Risky)
๐ป Code Snippet
XML
substring(
$filename,
1,
oraext:last-index-within-string($filename, '.')
)
✔️ Behavior
Dynamically trims extension
Works for any filename length
๐ Advantages
Fully dynamic
Handles multiple dots easily
๐ Disadvantages
❌ In OIC mapper, sometimes does not evaluate correctly
Can fail depending on context (Stage File / namespaces)
Less predictable compared to substring chaining
๐ง Recommended Hybrid Logic
๐ Best practical approach:
Use substring logic when:
File pattern is fixed (like a.b.c.csv.pgp)
Use last-index logic when:
File pattern is dynamic
Tested properly in your integration
๐ Pro Tip
If your only goal is to remove .pgp, a simpler and safer approach:
XML
fn:replace($filename, '.pgp', '')
✔️ Works for both cases:
a.b.c.csv.pgp → a.b.c.csv
a.b.c.csv → unchanged
๐งพ Conclusion
OIC file handling becomes tricky with multiple dots
substring-before → stable but rigid
last-index-within-string → flexible but unreliable in some cases
๐ฏ Best solution depends on your file pattern stability
OIC CCS Utility Adapter – Misleading “Client ID Wrong” Error (Actual Issue: Catalog Not Configured)
๐ Overview
While configuring a CCS (Customer Cloud Service) / Utilities Adapter connection in Oracle Integration Cloud (OIC) using Client Credentials, you might encounter an error stating:
❌ “Client ID is invalid” or “Client credentials are incorrect”
At first glance, this looks like an authentication issue—but that’s not always the case.
This blog explains a real scenario where the credentials were correct, but the actual issue was missing Web Service Catalog configuration in CCS.
⚠️ The Problem Statement
You create an OIC connection using:
Security Policy: OAuth Client Credentials
Correct Client ID & Secret
While testing the connection:
❌ Error: Invalid Client ID / Authentication Failed
Even after rechecking:
Credentials ✔️
Token URL ✔️
Scope ✔️
Still failing.
๐ง Root Cause (Hidden Issue)
The actual issue was:
๐จ Web Service Catalog was NOT configured in the CCS (Utilities) portal
Without this configuration:
OIC cannot discover or invoke backend services
The adapter fails internally
And misleadingly throws authentication-related errors
๐ What is Web Service Catalog?
The Web Service Catalog in Oracle Utilities defines:
Which REST services are exposed
Which services OIC can access via the Utilities Adapter
Without it, even valid credentials won’t help.
๐ ️ Fix: Configure Catalog in CCS
Follow these steps:
1️⃣ Login to CCS / Utilities Portal
2️⃣ Navigate to: Admin → Integration / W → Web Service Catalog
3️⃣ Select: REST Web Service Class
4️⃣ Add Required Services:
W1-ServiceCall → Service Call Maintenance
W1-Communication → Communication Maintenance
๐ These are essential inbound services for OIC communication.
๐ Retest in OIC
After configuring the catalog:
Go back to OIC Connection
Click Test
✅ Connection should now succeed
๐ก Key Takeaways
❌ Don’t trust error messages blindly in OIC
๐ “Invalid Client ID” ≠ Always authentication issue
⚙️ Always verify:
Catalog configuration in CCS
Required REST services availability
๐ Pro Tip
When working with Oracle Utilities Adapter:
Always validate backend readiness (Catalog + Services) before debugging authentication
If error feels misleading → check service exposure first
๐งพ Conclusion
This issue is a classic example where:
Everything looks like a security problem
But turns out to be a configuration gap in backend
Fixing the Web Service Catalog resolved the issue completely—without changing any credentials.
Reference:
Friday, April 17, 2026
OIC XSLT: Execute Only When At Least One Field Has Value and None Are Blank
๐ท OIC XSLT: Validate Fields Before Executing Logic
๐น Requirement
Fields: field1, field2, field3, field4, field5
✔ Execute only when: At least one field has a value
AND no provided field is empty (including spaces)
๐น Final XSLT
XML
<xsl:if test="
(
string-length(normalize-space(field1)) > 0 or
string-length(normalize-space(field2)) > 0 or
string-length(normalize-space(field3)) > 0 or
string-length(normalize-space(field4)) > 0 or
string-length(normalize-space(field5)) > 0
)
and
(
(not(field1) or string-length(normalize-space(field1)) > 0) and
(not(field2) or string-length(normalize-space(field2)) > 0) and
(not(field3) or string-length(normalize-space(field3)) > 0) and
(not(field4) or string-length(normalize-space(field4)) > 0) and
(not(field5) or string-length(normalize-space(field5)) > 0)
)
">
<!-- Execute logic -->
</xsl:if>
๐น Key Idea (1 Line)
๐ Run only if:
At least one field has non-space value AND no field is empty/blank
๐น Why normalize-space() Matters
Converts " " → ""
Prevents false positives from whitespace
Ensures clean validation in OIC payloads
๐น Quick Examples
Input == Result
<root/>❌ Skip
<field1> </field1> ❌ Skip
<field1>ABC</field1> ✅ Execute
<field1>ABC</field1><field2> </field2> ❌ Skip
Wednesday, April 15, 2026
OIC - Handling Base64 Encoded JSON NXSD Parsing Issue in Oracle Integration Cloud (OIC)
๐ Problem Statement
In a Real-Time REST integration in Oracle Integration Cloud, the source system sends Base64 encoded JSON.
Flow:
Receive Base64 payload
Decode using oraext:decodeBase64()
Pass to Stage File → Read as JSON
❗ Issue Faced
After decoding, the JSON becomes invalid because:
The closing curly brace } is missing
This causes NXSD parsing errors in Stage File
๐ Root Cause
During decoding or transformation:
Extra whitespace / formatting issues
Improper encoding at source
OIC string handling edge cases
๐ Result: JSON becomes malformed, especially missing }
๐ก Solution Approach
Instead of directly parsing decoded JSON:
✅ Step 1: Decode Base64
✅ Step 2: Clean the JSON string
✅ Step 3: Validate & fix missing closing brace
✅ Step 4: Re-encode to Base64
✅ Step 5: Pass as Opaque to Stage File
๐ ️ Implementation (XSLT Logic)
✅ Step 1: Decode Base64
Xslt
<xsl:variable name="decoded"
select="oraext:decodeBase64(/nssrcmpr:execute/ns16:request-wrapper/ns16:message)"/>
✅ Step 2: Clean unwanted whitespace
Xslt
<xsl:variable name="cleaned"
select="replace($decoded, '(:\s*")\s+', '$1')"/>
๐ Removes unnecessary spaces after : in JSON
✅ Step 3: Fix Missing Closing Brace
Xslt
<xsl:variable name="finalJson">
<xsl:choose>
<xsl:when test="contains($cleaned, '}')">
<xsl:value-of select="$cleaned"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($cleaned, '}')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
๐ Ensures JSON is always valid
✅ Step 4: Encode Back to Base64
Xslt
<xsl:value-of select="oraext:encodeBase64($finalJson)"/>
๐ Integration Flow Design
๐งฉ OIC Flow Steps
REST Trigger
Stage File (Write File)
Write as Opaque
Use above XSLT
Stage File (Read File)
Now JSON is valid
Parse using NXSD schema
Continue processing…
๐ฏ Why Opaque Handling Works
Using opaque avoids:
Early validation failures
NXSD parsing errors on invalid JSON
๐ You fix JSON before parsing
⚠️ Best Practices
Always validate decoded payload:
Use contains() or ends-with() for }
Log decoded payload (for debugging)
Avoid direct parsing of decoded Base64 without validation
๐ Conclusion
Handling Base64 JSON in OIC can be tricky due to:
Encoding inconsistencies
Transformation side effects
๐ The decode → clean → fix → re-encode → stage as opaque pattern is a reliable solution.
Code screenshots:
Stage write:
Read json:
Code snippet:
<xsl:template match="/" xml:id="id_11">
<nstrgmpr:Write xml:id="id_12">
<ns31:opaqueElement>
<!-- Step 1: Decode -->
<xsl:variable name="decoded" select="oraext:decodeBase64(/nssrcmpr:execute/ns16:request-wrapper/ns16:message)"/>
<!-- Step 2: Clean whitespace after ":" -->
<xsl:variable name="cleaned"
select="replace($decoded, '(:\s*")\s+', '$1')"/>
<!-- Step 3: Check and fix closing brace -->
<xsl:variable name="finalJson">
<xsl:choose>
<xsl:when test="contains($cleaned, '}')">
<xsl:value-of select="$cleaned"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($cleaned, '}')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Step 4: Encode back -->
<xsl:value-of select="oraext:encodeBase64($finalJson)"/>
</ns31:opaqueElement>
</nstrgmpr:Write>
</xsl:template>
Featured Post
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.*; im...
-
OIC interview Q & A: We have divided the interview questions into 3 sections: Non- Technical, Technical shorts and Scenario based questi...
-
Please find the following links for OIC hands on and relevant information: Oracle Integration Cloud Introduction | Benefits | Services offer...
-
Stage or vfs or virtual file system is a temporary location in the oic local file system which stores temporary files required for processin...
-
In Oracle Integration Cloud (OIC), the most commonly used XSLT functions are primarily focused on transforming, filtering, and manipulating ...
-
OIC generation 3 links: Oracle Integration Generation 3 New Features Integration patterns and how to define schedules About RBAC - Resource ...
-
Usecase: Here, we will demonstrate the detailed implementation steps for AP Invoice FBD Import from polling the file from source >> cr...
-
Following are the oracle fusion job schedule processes tables which helps to extract the submitted ESS job requests: ESS_Request_History ESS...
-
Use Case : In a utility integration scenario using MultiSpeak-compliant web services, a SOAP request fails with the error: "CASDK-003...
-
๐งพ Use Case Overview In most Oracle Fusion implementations, File-Based Data Import (FBDI) is a widely used approach to load master and tran...
-
Usecase: Here, we will extract the data from HCM and then download the data from UCM uaing Flow Actions Service and Generic Soap Service To...





















