+ Start a Discussion

How to convert the AES-256 key and Initial vector with the public RSA Key(.PEM file) shared by third party system

Problem:-  How to convert the AES-256 key and Initial vector with the public RSA Key (Shared by third party system Agreement Express)
1. Randomly generate a AES-256 key.
2. Randomly generate an IV.
3. Encrypt the json with the AES key and IV, base64-encode it, and set it as the request
4. Encrypt the AES key with the public RSA key and base64-encode it
5. Encrypt the IV with the public RSA key and base64-encode it
 From the above requirement, I am able to implement the point 1, 2, and 3. Now the technical challenge which we are facing here is, how to convert the AES-256 key and initial vector with the public RSA Key shared by third party system?
Approach one:-
I tried with below code and getting following error System.SecurityException: Invalid Crypto Key”
 Blob encryptedData = Crypto.sign(RSA, AEX-256 Key, AEXThirdPartyPublicKey );
Approach two:- Tried below, however client is getting  "java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block"

Please let me know if anybody would have came across above scenario. Client shared Public key in .Pem format not the private key.
Approche one  Blob encryptedData = Crypto.sign(‘RSA‘, ‘AEX-256 Key’, ‘AEXThirdPartyPublicKey );
I could able to implement as below:- By using Open SSL use below command to get the module and exponent openssl rsa -pubin -in pubkey.txt -text -noout (Remove (:) from Module ...

  Blob aesKey = Crypto.generateAesKey(256); // Random generated value
        Blob initialVector = Crypto.generateAesKey(128);// Random generated value

 HttpRequest httpRequest = new HttpRequest();  
         //  httpRequest.setEndPoint('https://requestb.in/zno8xizn');
            httpRequest.setHeader(Constants.Authorization, authorization);
            httpRequest.setHeader(Constants.Key, encryptMyKeys(aesKey));
            httpRequest.setHeader(Constants.Iv, encryptMyKeys(initialVector));
            System.debug('requestJSON @@'+requestJSON);
            logger = new API_Utils_Logger(httpRequest, Constants.AEX_Publish_Api_Name);
public static String encryptRequest(String jsonRequestBody,Blob aesKey, Blob initialVector ) {     
        Blob jsonRequestBodyObject = blob.valueOf(jsonRequestBody);
        Blob encryptedData = Crypto.encrypt(Constants.Advanced_Encryption_Standard, aesKey, initialVector, jsonRequestBodyObject);       
        return EncodingUtil.base64Encode(encryptedData);   
    public static String encryptMyKeys(Blob keyValue) {    
       String modules = '';
       String exponent = '';
       List<EncryptKeys__mdt> moduleList = [select AEX_MODULE_EXPONENT_FROM_PEM_FILE__c from EncryptKeys__mdt where EncryptKeys__mdt.MasterLabel='AEX_MODULE_FROM_PEM_FILE'];
       List<EncryptKeys__mdt> expoentList = [select AEX_MODULE_EXPONENT_FROM_PEM_FILE__c from EncryptKeys__mdt where EncryptKeys__mdt.MasterLabel='AEX_EXPONENT_FROM_PEM_FILE'];
        for(EncryptKeys__mdt moduleObject :moduleList){
           modules = moduleObject.AEX_MODULE_EXPONENT_FROM_PEM_FILE__c; 
        for(EncryptKeys__mdt expoentObject:expoentList ){
           exponent = expoentObject.AEX_MODULE_EXPONENT_FROM_PEM_FILE__c;
        System.debug('modules ## '+modules +' exponent @@ '+exponent );
        String encModules =  EncodingUtil.base64Encode( EncodingUtil.convertFromHex(modules) ); 
        RsaEncryptionInitialSubmissionApi  rsa = new RsaEncryptionInitialSubmissionApi(encModules ,exponent);
        String  encryptedKey = rsa.encrypt(EncodingUtil.base64Encode(keyValue));
        return encryptedKey ;

public with sharing class RsaEncryptionInitialSubmissionApi{

    private String modulus;
    private String exponent;

    // Hex digits
    private static final String DIGITS = '0123456789abcdef';
    private static final Decimal HEX_BASE = 16;

    public RsaEncryptionInitialSubmissionApi(String modulus, String exponent) {
        this.modulus = modulus;
        this.exponent = exponent;

    public String encrypt(String input) {
        Blob mod = EncodingUtil.base64Decode(modulus);
        //Blob exp = EncodingUtil.base64Decode(exponent);
         System.debug('mod size ::'+mod.size());
        // Pad password.nonce
        Blob pn = Blob.valueOf(String.fromCharArray(pkcs1Pad2(input, mod.size()-1)));

        Decimal modDec = hexToDecimal(EncodingUtil.convertToHex(mod));
        Decimal expDec =decimal.valueOf(exponent);// hexToDecimal(EncodingUtil.convertToHex(exp));
        Decimal pnDec = hexToDecimal(EncodingUtil.convertToHex(pn));

        System.debug('modDec :::: '+modDec );
        System.debug('expDec :::: '+expDec );
        // Calcluate padded^exp % mod and convert to hex
        Decimal result = modPow(pnDec, expDec, modDec);
        String hexResult = decimalToHex(result);
        // If length is uneven, add an extra 0
        if ((hexResult.length() & 1) == 1) {
            hexResult = '0' + hexResult;

        // Generate the data to be encrypted.
        Blob encodedData = EncodingUtil.convertFromHex(hexResult);
        return EncodingUtil.base64Encode(encodedData);

    private static Decimal hexToDecimal(String hex) {
        Decimal result = 0;
        integer length = hex.length();
        integer i = 0;
        while(i < length) {
            integer hexByte = DIGITS.indexOf(hex.substring(i, i + 1).toLowerCase());
            result += hexByte * HEX_BASE.pow(length - i);
        return result;

    private static String decimalToHex(Decimal d) {
        String hex = '';
        while (d > 0) {
            Decimal digit = modulus(d, HEX_BASE); // rightmost digit
            hex = DIGITS.substring(digit.intValue(), digit.intValue() + 1) + hex; // string concatenation
            d = d.divide(16, 0, RoundingMode.FLOOR);
        return hex;