1

I have some data from a external party which is encrypted according to them in: 'Rijndeal 256 with the private key'

Alongside these records there are a public and private key certificate which look like RSA certificates.

From what i've learned so far it seems the common way to use encryption with certifcates is to generate a 'secret key' or some kind in initialization vector and use this to encrypted text. So i'm thinking this is probably what they have done (the data was encrypted by a PHP application)

I'm trying to decrypt this text with javax.crypto.Cipher but i think i problably need more information on the specific encryption, but i dont really know what information to ask for, and think its likely the 'default options' will probably work. (Communication with the supplying party is difficult and slow).

i'm currently Using the following code to get the private key:

  InputStreamReader ir = new InputStreamReader(the_inputstream_for_the_private_key_record);
   Security.addProvider(new BouncyCastleProvider());
   pemr = new PEMReader(ir);
   Object o = pemr.readObject();
   keyPair kp = (KeyPair) o;
   return kp.getPrivate();

This seems to work as i get a instantiated PrivateKey object without errors the toString looks like:

RSA Private CRT Key
            modulus: c98faa50ba69<trimmed>
    public exponent: 10001
   private exponent: bb889fbe5cb2a6763f...<trimmed>
             primeP: eb73e85dc636f5751b...<trimmed>
             primeQ: db269bd603a2b81fc9...<trimmed>
     primeExponentP: 85b9f111c190595cc8...<trimmed>
     primeExponentQ: a66d59a75bb77530de...<trimmed>
     crtCoefficient: 79415b078c4c229746...<trimmed>

For each record i also have a entry like the following:

{
"decryptedLength":128389,
"symKeyLength":32,
"symKey":"SImE8VnSZaAu1Ve...<trimmed (this is always 685 chars long) >...ayaJcnpSeOqAGM7q="
}

Basically this is where i'm a bit stuck. My guess would be that that 'symkey' value is encrypted with RSA which in turn when decrypted would yield the secretKey for the AES part, but if i try:

Cipher rsaCipher = Cipher.getInstance("RSA");
rsaCipher.init(Cipher.DECRYPT_MODE, key);
byte[] b = rsaCipher.doFinal('symkey'.getbytes());

this gets me "javax.crypto.IllegalBlockSizeException: Data must not be longer than 512 bytes", which seems logical since this string is 685characters long

I'm probably missing something very obvious here... Any suggestions are appreciated.

pvgoddijn
  • 12,638
  • 15
  • 47
  • 56

3 Answers3

2

Just guessing, but I think the value

"symKey":"SImE8VnSZaAu1Ve...<trimmed (this is always 685 chars long) >...ayaJcnpSeOqAGM7q="

is the base64 encoded output from RSA encryption using a 4096-bit public key. You need to first base64 decode the value into a byte[] array, then decrypt it with the private key, the result of which will be a 256-bit key. Note that "Rijndael 256" is ambiguous, since Rijndael supports both a 256 bit blocksize and also a 256 bit keysize.

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
1

with GregS's answer i finaly got this to work. (adding an answer in case someone else needs to decrypt similar php encoded stuff).

The first part was to decrypt de symmetricKey ("symkey") from the metaData string This was as Greg notes a Base64 encoded, RSA encrypted key which was decoded like so:

Cipher rsaCipher = Cipher.getInstance("RSA");
rsaCipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedRijndaelKey = Base64.decodeBase64(base64EncodedSymetricKey); //from the metaData
byte[] rijndaelKeyBytes = rsaCipher.doFinal(encryptedRijndaelKey);

This Rijndael key was then used to decrypt de actual encrypted data like so:

RijndaelEngine rijndaelEngine = new RijndaelEngine(256); // *1 *2
KeyParameter keyParam = new KeyParameter(rijndaelKeyBytes)
rijndaelEngine.init(false, keyParam);  //false == decrypt
PaddedBufferedBlockCipher bbc = new PaddedBufferedBlockCipher(rijndaelEngine, new ZeroBytePadding()); // *3 

byte[] decryptedBytes = new byte[decryptedLenght]; //from the storageOptions string
int processed = bbc.processBytes(inputBytes, 0, inputBytes.length, decryptedBytes, 0);
bbc.doFinal(decryptedBytes, processed);

*1 because the Sun JCA only supports common AES which has a 128bits keysize i had to use a different provider (BouncyCastle). *2 apparently the blocksize was also 256 bits (trail & error) *3 apparently there was no padding used, thus the ZeroPadding for padding (again trail & error).

pvgoddijn
  • 12,638
  • 15
  • 47
  • 56
0

The symKey value is Base64 encoded and must be decoded before you can do the private key decryption on it. Also, the symmetric encryption sounds like it is AES-256. (AES is based on the Rijndael cipher).

John Haager
  • 2,107
  • 1
  • 17
  • 22