2

SO if i am given a private key as follow:

[242, 2, 56, 23, 15, 5, 12, 105, 19, 47, 116, 89, 25, 152, 200, 215]

and an initialization vector:

[194, 125, 123, 26, 93, 136, 191, 35, 20, 86, 167, 197, 12, 138, 135, 92, 233, 39, 121, 166, 8, 2, 103, 44, 239, 115, 50, 155, 200, 238, 33, 99]

How would I go about using Crypto.encrypt in Apex? The example I found all use Strings for the iV and use an auto generatedKey as shown below:

Blob exampleIv = Blob.valueOf('Example of IV123');
Blob key = Crypto.generateAesKey(128);
Blob data = Blob.valueOf('Data to be encrypted');
Blob encrypted = Crypto.encrypt('AES128', key, exampleIv, data);

Do I just do this?

String encodedString = String.fromCharArray(ivKey);

Somehow something does not feel right here, my private key as 16 numbers and my iv has 32, these are provided from a third party so I HAVE to use keys like the one I posted (the two keys I posted I generated at random for obvious security purpose). I am just trying to understand how to make this work in Apex if at all possible

Any help would be appreciated!

UPDATE:

Using the code below:

List<Integer> key = new List<Integer>{242, 2, 56, 23, 15, 5, 12, 105, 19, 47, 116, 89, 25, 152, 200, 215};
List<Integer> iv = new List<Integer>{194, 125, 123, 26, 93, 136, 191, 35, 20, 86, 167, 197, 12, 138, 135, 92, 233, 39, 121, 166, 8, 2, 103, 44, 239, 115, 50, 155, 200, 238, 33, 99};

String charkey = Base64.encode(key);
String chariV = Base64.encode(iv);
String password ='passwd9999';

Blob Blobkey =  EncodingUtil.base64Decode(charkey);
Blob BlobiV =  EncodingUtil.base64Decode(chariV);
Blob BlobPassword = Blob.valueOf(password);

Blob encrypted = Crypto.encrypt('AES128', Blobkey, BlobiV, BlobPassword);
String encryptedDataStr = EncodingUtil.base64Encode(encrypted);
System.Debug(encryptedDataStr);

with this class:

public class Base64 {
    static String[] codes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split('');

    // Encodes integers 0-255 into base 64 string
    public static String encode(Integer[] source) {
        // Preallocate memory for speed
        String[] result = new String[(source.size()+2)/3];
        // Every three bytes input becomes four bytes output
        for(Integer index = 0, size = source.size()/3; index < size; index++) {
            // Combine three bytes in to one single integer
            Integer temp = (source[index]<<16|source[index+1]<<8)|source[index+2];
            // Extract four values from 0-63, and use the code from the base 64 index
            result[index]=codes[temp>>18]+(codes[(temp>>12)&63])+(codes[(temp>>6)&63])+codes[temp&63];
        }
        if(Math.mod(source.size(),3)==1) {
            // One byte left over, need two bytes padding
            Integer temp = (source[source.size()-1]<<16);
            result[result.size()-1] = codes[temp>>18]+(codes[(temp>>12)&63])+codes[64]+codes[64];
        } else if(Math.mod(source.size(),3)==2) {
            // Two bytes left over, need one byte padding
            Integer temp = (source[source.size()-2]<<16)|(source[source.size()-1]<<8);
            result[result.size()-1] = codes[temp>>18]+(codes[(temp>>12)&63])+(codes[(temp>>6)&63])+codes[64];
        }
        // Join into a single string
        return String.join(result, '');
    }
}

I get the following error:

System.InvalidParameterValueException: Invalid private key. Must be 16 bytes.

I wish I did not have to use an Integer Array but I do not have much choice in the matter!

1 Answer 1

1

We do not use a String for encryption, we use a Blob. The easiest way to get where you're trying to go is to use EncodingUtil's base64Decode function to the the format you need:

Blob exampleIv = EncodingUtil.base64Decode('yourBase64EncodedIvHere');
Blob key = EncodingUtil.base64Decode('yourBase64EncodedKeyHere');

As we discussed in your previous question, if you absolutely insist on using an Integer array, you can use the code I put in my previous answer to convert it to a base64 string, but you'll still need to use this decode method to get to the correct Blob data values.

7
  • I did that but I get: System.InvalidParameterValueException: Invalid private key. Must be 16 bytes. And unfortunately I do not have a choice with the Integer array.
    – Tekill
    Nov 14, 2016 at 18:47
  • I really appreciate your help and I posted the code above but unfortunately it is not working!
    – Tekill
    Nov 14, 2016 at 18:50
  • @Tekill Why do you not have a choice? There's no practical difference between a base64-encoded string and an array of integers once it finally gets converted to binary data...
    – sfdcfox
    Nov 14, 2016 at 18:52
  • @Tekill By the way, I just realized what you're trying to do. The IV and Key must be the same size for AES. There's absolutely no way a 128 bit key with a 256 bit IV is going to work with AES. What encryption algorithm are they trying to have you use?
    – sfdcfox
    Nov 14, 2016 at 19:01
  • perhaps I am just being stubborn and would like to get a solution where I can just input the keys that are being given to me, I tried with the Base64 string right of the bat but I keep getting the: "System.InvalidParameterValueException: Invalid private key. Must be 16 bytes."
    – Tekill
    Nov 14, 2016 at 19:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.