Do not decrypt what I encrypted

I have a strange problem ...

The Basics of My Decision on Decrypting a Hard File as Byte []

So, I wrote a small Cypher class to help with encryption / decryption ... He used for the layout a key hardcoded in some place, and another pre-encrypted key stored somewhere else. But this is somewhat inappropriate.

The encryption process went as follows:

  • get an array of hard-coded bytes
  • use it to decrypt key2
  • use key2 to decrypt data
  • use key1 to further decrypt the data.
  • have decrypted data

I stored the encrypted data as a hexadecimal string, used these two functions to go back and forth

private static String byteArrayToHexString(byte[] b) { StringBuffer sb = new StringBuffer(b.length * 2); for (int i = 0; i < b.length; i++) { int v = b[i] & 0xff; if (v < 16) { sb.append('0'); } sb.append(Integer.toHexString(v)); } return sb.toString().toUpperCase(); } private static byte[] hexStringToByteArray(String s) { byte[] b = new byte[s.length() / 2]; for (int i = 0; i < b.length; i++) { int index = i * 2; int v = Integer.parseInt(s.substring(index, index + 2), 16); //THIS LINE b[i] = (byte) v; } return b; } 

It worked flawlessly; in fact, it worked so well that I implemented it in my real project. The project could not be launched due to the fact that I did not pass a thorough test.

It turns out that he encrypts / decrypts almost all files, except for one - one that does not want to decrypt.

I pointed out the problem exactly - this line throws an IllegalNumberFormat exception; at some point I met this http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6259307 . I could return to this method if someone describes a way around the case where a string of length 2 is converted to four bytes that throw an IllegalNumberFormat exception.

So, I thought that since I can’t decode the file (and obviously I can’t share it here, for you guys to try) I needed to somehow convert it to make it transport. Enter a Base64Coder class that encodes base64 strings ...

It seemed that she introduced a new problem - the filling was filled.

The question is simple - what am I doing wrong? I have to match this data, and it should be able to glue / decrypt correctly and equally. I would like the suggestion of the easiest solution to be possible with minimal copy / paste ... the pseudocode will not do the trick here.

Here is what I am doing now ....

 public static char[] encrypt2(byte[] value) throws GeneralSecurityException, IOException { SecretKeySpec key1 = getSecretKeySpec(true); System.err.println("encrypt():\t" + key1.toString()); Cipher cipher = Cipher.getInstance(CRYPTOSYS); cipher.init(Cipher.ENCRYPT_MODE, key1, cipher.getParameters()); byte[] encrypted = cipher.doFinal(value); SecretKeySpec key2 = getSecretKeySpec(false); cipher = Cipher.getInstance(CRYPTOSYS); cipher.init(Cipher.ENCRYPT_MODE, key2, cipher.getParameters()); byte[] encrypted2 = cipher.doFinal(encrypted); return Base64Coder.encode(encrypted2); } public static byte[] decrypt2(char[] message) throws GeneralSecurityException, IOException { SecretKeySpec key1 = getSecretKeySpec(false); System.err.println("decrypt():\t" + key1.toString()); Cipher cipher = Cipher.getInstance(CRYPTOSYS); cipher.init(Cipher.DECRYPT_MODE, key1); byte[] decrypted = cipher.doFinal(Base64Coder.decode(message)); SecretKeySpec key2 = getSecretKeySpec(true); cipher = Cipher.getInstance(CRYPTOSYS); cipher.init(Cipher.DECRYPT_MODE, key2); byte[] decrypted2 = cipher.doFinal(decrypted); return decrypted2; } 

Please note that the keys are currently fully open (hard-coded) for testing purposes.

Here is my test case

 public static void main(String... args) throws Exception { // byte[] data = "hello".getBytes(); File PEM = new File(PATH_TO_FILES + SOURCE_PEM); File DER = new File(PATH_TO_FILES + SOURCE_DER); File cryptoPEM = new File(PATH_TO_FILES + "cryptopem"); File cryptoDER = new File(PATH_TO_FILES + "cryptoder"); byte[] cryptokey = encryptA(ASSET_KEY); System.out.println(new String(cryptokey)); //pem key System.out.println("PEM"); byte[] data = getBytesFromFile(PEM); char[] crypted = encrypt2(data); // FileOutputStream fos = new FileOutputStream(cryptoPEM); FileWriter fw = new FileWriter(cryptoPEM); fw.write(crypted); fw.flush(); //der key System.out.println("DER"); data = getBytesFromFile(DER); crypted = encrypt2(data); fw = new FileWriter(cryptoDER); fw.write(crypted); fw.flush(); //opentext System.out.println("checking PEM..."); crypted = Base64Coder.encode(getBytesFromFile(cryptoPEM)); byte[] decrypted = decrypt2(crypted, false); byte[] decryptedData = decrypted; if (!Arrays.equals(getBytesFromFile(PEM), decryptedData)) { throw new Exception("PEM Data was not decrypted successfully"); } System.out.println("checking DER..."); crypted = Base64Coder.encode(getBytesFromFile(cryptoDER)); decrypted = decrypt2(crypted, false); decryptedData = decrypted; if (!Arrays.equals(getBytesFromFile(DER), decryptedData)) { throw new Exception("DER Data was not decrypted successfully"); } } 

And now I get an InvalidBlockSizeException .... Please someone shed some light on this, I just want it to work ...

Replacing "key2" for IV, which will later be used in "AES / CBC / PKCS5Padding", is an option that I am considering right now. Essentially, nothing will change except the second step of encryption. Theoretically and by the method, I would keep the same thing - unless, of course, the best solution is described.

In the end, I would like to point out that this is a programmer’s question and not a question of IT security, so the correct code is evaluated more than the theoretical answer, which covers unlikely cases.

EDIT: well, I can't give you the numbers that raise the IllegalNumberFormatException, because I lost the code in the morning. I can not reproduce the problem, so I think I'm trying to understand that this part is useless.

Here is the sample test result:

 encrypt(): javax.crypto.spec.SecretKeySpec@15dd7 5@  _׵G j  ! c;D i lR?z j\ PEM encrypt(): javax.crypto.spec.SecretKeySpec@15dd7 DER encrypt(): javax.crypto.spec.SecretKeySpec@15dd7 checking PEM... decrypt(): javax.crypto.spec.SecretKeySpec@15c78 Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher 

which means Base64 just messed it up ...

+1
java android base64 encryption aes
Aug 30 '12 at 13:40
source share
3 answers

After reviewing the code this morning and tweaking a bit, I got it to work.

 public static byte[] encrypt2(byte[] value) throws GeneralSecurityException, IOException { SecretKeySpec key1 = getSecretKeySpec(true); System.err.println("encrypt():\t" + key1.toString()); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key1, cipher.getParameters()); byte[] encrypted = cipher.doFinal(value); SecretKeySpec key2 = getSecretKeySpec(false); System.err.println("encrypt():\t" + key2.toString()); cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key2, new IvParameterSpec(getIV())); byte[] encrypted2 = cipher.doFinal(encrypted); return encrypted2;//Base64Coder.encode(encrypted2); } public static byte[] decrypt2(byte[] message, boolean A) throws GeneralSecurityException, IOException { SecretKeySpec key1 = getSecretKeySpec(false); System.err.println("decrypt():\t" + key1.toString()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key1, new IvParameterSpec(getIV())); byte[] decrypted = cipher.doFinal(message); SecretKeySpec key2 = getSecretKeySpec(true); System.err.println("decrypt():\t" + key2.toString()); cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key2); byte[] decrypted2 = cipher.doFinal(decrypted); return decrypted2; } 
0
Aug 31 2018-12-12T00:
source share

I think the problem is here:

 //opentext System.out.println("checking PEM..."); crypted = Base64Coder.encode(getBytesFromFile(cryptoPEM)); 

You used to add char [] to the file, but now you read byte [] from the file and transcode to base64. The contents of the file should already be encoded in base64!

You need a new function called getCharsFromFile that returns a char [] or String and passes that value directly to decrypt2.

+1
Aug 30 '12 at 15:33
source share
0
Aug 30 '12 at 15:48
source share



All Articles