Java decryption and encryption compatible with SJCL?

I need to encrypt and decrypt data from both Java (on Android) and SJCL (I could plausibly switch to another JS cryptographic library, but I am familiar with SJCL, so I would prefer to stick with it if possible).

I have the end of SJCL, but at the end of Java I’m not quite sure which parameters I need to use to configure the key generator and encryption. The code I still used to decrypt:

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 1024, 256); SecretKey tmp = factory.generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv)); String plaintext = new String(cipher.doFinal(ciphertext), "UTF-8"); return plaintext; 

When salt, iv and ciphertext are extracted as strings from a JSON object created by SJCL, and then decoded using Base64 decoder into byte arrays.

Unfortunately, I have a few problems with this, and the code above does not work.

The first problem is that PBKDF2WithHmacSHA256 does not seem to be a recognized key generation algorithm. I'm not quite sure if this is what I want, but it seems to be correct based on reading the SJCL documentation? Java recognizes PBKDF2WithHmacSHA1, but this is not like the same algorithm that implements SJCL.

Secondly, if I try to use the SHA1 key algorithm, I get an error message with an invalid key size. Do I need to install something to enable AES with 256-bit keys? Calling a factory key to create a 128-bit key works fine (although, obviously, it is not compatible with SJCL, which uses a 256-bit key).

Third, what encryption mode should I use? I'm sure CBC is wrong ... The SJCL documentation mentions both CCM and OCB, but Java doesn't seem to support any of them out of the box - again, do I need to install something to make this work? And which one uses SJCL by default?

And finally, even if I choose the parameters that cause Java not to complain about the missing algorithms, he complains that the IV provided by decoding the SJCL output is of the wrong length, which certainly looks like this: the result is a 17 byte output, not 16, as AES seems to require. Am I just ignoring the last byte?

+4
source share
2 answers

I did not try (in the end, I refused to use Javascript cryptography in favor of using the built-in java applet with bouncycastle to handle communication), but GnuCrypto (the bouncycastle fork) supports PBKDFWithHmacSHA256. Fixed character encoding processing in SJCL presumably captures an unexpected IV (?) Length, so this will just leave the encryption mode. From this point of view, it seems that the easiest approach would be to introduce a relatively simple encryption mode (for example, CTR) as an add-on for SJCL, which should be only a few hours of work even for someone unfamiliar with the code, after which this is just a question encoding and decoding JSON-encoded data packets that are used by SJCL (which should be trivial).

Alternatively, it would be possible to implement the OCB mode for Java, despite the fact that the algorithm is proprietary, as there is a public patent grant for software distributed under the GPL (http: //www.cs. Ucdavis.edu/~rogaway /ocb/grant.htm).

I wonder if it is interesting that GnuCrypto will accept a patch to support OCB mode? GnuCrypto is licensed under the GPL-with-libraries, which appears to qualify as "any version of the GNU General Public License published by the Free Software Foundation", so theoretically, at least, it should be possible.

+1
source

You may need to use BouncyCastle to get all the cryptographic functions used in SJCL. Make sure you decode base64 correctly and that SJCL does not add length indicators or similar.

-one
source

Source: https://habr.com/ru/post/1398348/


All Articles