Code Monkey home page Code Monkey logo

jncryptor's Introduction

JNCryptor

JNCryptor is an easy-to-use library for encrypting data with AES. It was ported to Java from the RNCryptor library for iOS.

The project is considered finished, hence the lack of recent activity. Please raise issues for any problems encountered.

Getting JNCryptor

The Javadocs can be browsed online: JNCryptor Javadocs.

You can download binaries, documentation and source from the Releases page. Maven users can copy the following snippet to retrieve the artifacts from Maven Central:

<dependency>
    <groupId>org.cryptonode.jncryptor</groupId>
    <artifactId>jncryptor</artifactId>
    <version>1.2.0</version>
</dependency>

Using JNCryptor

A quick example is shown below:

JNCryptor cryptor = new AES256JNCryptor();
byte[] plaintext = "Hello, World!".getBytes();
String password = "secretsquirrel";

try {
  byte[] ciphertext = cryptor.encryptData(plaintext, password.toCharArray());
} catch (CryptorException e) {
  // Something went wrong
  e.printStackTrace();
}

Android

Users have reported significant performance issues when using this library in Android (see Issue #23 for more info).

Android is not a tested nor supported platform for JNCryptor and there are no plans to address these performance issues. Please take a look at other projects, such as https://github.com/TGIO/RNCryptorNative, which aim to plug this gap with native code solutions.

IMPORTANT: Due to a bug in the Android SecureRandom implementation, JNCryptor is not currently safe to use in Android versions prior to 4.4. Please see an announcement from Google from back in 2013. The issue is tracked here as Issue #25, but will not be fixed in this project.

Iterations

JNCryptor supports changing the number of PBKDF2 iterations performed by the library. Unfortunately, the number of iterations is not currently encoded in the data format, which means that both sides of the conversation need to know how many iterations have been used.

Data Format

A proprietary data format is used that stores the IV, salt values (if applicable), ciphertext and HMAC value in a compact fashion. Methods are offered to encrypt data based on either an existing key, or a password. In the latter case, a key is derived from the password using a key derivation function, with 10,000 iterations and a salt valu.e

See the spec documents online.

Keys are derived from the password and the appropriate salt value using the PBKDF2 function with SHA1. A separate key is generated for encrypting the plaintext and computing the HMAC.

History

The data format supported by this library is v3. Both v1 and v0 have a significant security flaw whereby only the ciphertext was included in the HMAC value. There are no plans to support v1 or v0. v2 was deprecated due to a multi-byte password issue discovered in the objective-c implementation.

jncryptor's People

Contributors

dmjones avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jncryptor's Issues

Add streaming encryption/decryption

Reported by j.lammetje, Apr 16, 2013

When a user does not want to have the entire plaintext/ciphertext in memory, there is currently no option to encrypt parts of the text.

Adding methods that do not prepend a header and apend an hmac (or expect their input to have that) would solve this I think.

Add Possibility to Switch Security Provider

Hello there! I'm a fan of this library. It's very helpful.
Anyway, I come across that there should be a possibility to switch security provider as in JCE allows this as the following:

val cipher = Cipher.getInstance(DEFAULT_TRANSFORMATION, new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, loadPublicKey(publicKey));

I really appreciate your contribution to this library.
Looks forward to getting this on a future release.

Best Regard,

Reno

Did't support android studio 3.6.3

We have face the issue while upgrade the exist application.

Issues:

ERROR: Unable to find method 'com.android.build.gradle.internal.profile.ProfilerInitializer.init(Lorg/gradle/api/Project;)V'.
Possible causes for this unexpected error include:
Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)

Please help me

Throws exception while decrypting

    public static String encryptData(String data, String key) {
        byte[] decryptedData = data.getBytes();
        try {
            byte[] encryptedData = cryptor.encryptData(decryptedData, key.toCharArray());
            return new String(encryptedData);
        } catch (CryptorException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String decryptData(String data, String key) {
        try {
            byte[] encryptedData = data.getBytes();
            byte[] decryptedData = cryptor.decryptData(encryptedData, key.toCharArray());
            return new String(decryptedData);
        } catch (CryptorException e) {
            e.printStackTrace();
        }
        return null;
    }

I have used above encryption and decryption method.

org.cryptonode.jncryptor.InvalidHMACException: Incorrect HMAC value

I'm encrypting the data in Obj C and decrypting it in Java.

iOS Code to encrypt:

NSString *message = @"Hello World";
NSLog(@"message %@", message);

NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
NSString *password = @"secret8888656756secret8888656756";//tried 'secret' and 'secretsquirrell'

NSError *encryptionError = nil;
NSData *cipherData = [RNEncryptor encryptData:data withSettings:kRNCryptorAES128Settings password:password error:&encryptionError];

Java code to decrypt:

String password = "secret8888656756secret8888656756";
AES256JNCryptor cryptor = new AES256JNCryptor();

public String decrypt(byte[] encryptedData) {
    byte[] decryptData = null;
    try {
        decryptData = cryptor.decryptData(encryptedData,
                password.toCharArray());
    } catch (CryptorException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return new String(decryptData, Charset.forName("UTF-8"));
}

I'm getting the below error when decrypting encrypted data:

org.cryptonode.jncryptor.InvalidHMACException: Incorrect HMAC value.
at org.cryptonode.jncryptor.AES256JNCryptor.decryptV3Data(AES256JNCryptor.java:248)
at org.cryptonode.jncryptor.AES256JNCryptor.decryptV3Data(AES256JNCryptor.java:323)
at org.cryptonode.jncryptor.AES256JNCryptor.decryptData(AES256JNCryptor.java:280)
at com.fitzroy.cryptography.JNCryptor.decrypt(JNCryptor.java:29)
at com.fitzroy.service.CryptographyService.decrypt(CryptographyService.java:62)
at com.fitzroy.FitzroyResource.decrypt(FitzroyResource.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)

Please can you let me know if I'm doing anything wrong.

Salt (or IV)

I can see that both Salt (or IV) are being generated randomly, but let's say a user has two device A and B using the same app, would she be able to decrypt the data from device A on the device B without sharing Salt (or IV)?

Version byte set to '2' in key-based encryption method

Version 1.0.0 will produce a version 2 ciphertext when the key-based encryption method is used.

The consequences of this bug are minimal, since the two formats are identical in the Java implementation (save for the version byte), but clearly this must be fixed.

Unrecognised version number: 65

i'm developing an application for android and iOS which communicate with PHP server, i am using RNCryptor to encrypt the data between them.

For both iOS , PHP encryption/decryption are working fine but in android the decryption are not working and giving me org.cryptonode.jncryptor.CryptorException: Unrecognised version number:65.

After tracing your code in Android you are supporting 2 versions of codes "2","3" and my encryption from the server "PHP" is returing 65

So do you have any idea what i'm doing wrong ?

decode problem on android

i want to decode, an encrypted image on android, but what i get, is a corrupted file! am i doing it in a wrong way?!
here is my code base on sample code you made:

final String password = "my_password";

JNCryptor cryptor = new AES256JNCryptor();
Resources res = getResources();
InputStream in_s = res.openRawResource(R.raw.troodon_ph);
byte[] b = null;
byte[] data = null;
try {
  b = new byte[in_s.available()];
  in_s.read(b);
} catch (IOException e) {
  Log.i("decrypt error", e.toString());
}



AES256JNCryptorOutputStream cryptorStream = null;

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
  cryptorStream = new AES256JNCryptorOutputStream(byteStream,
      password.toCharArray());

} catch (CryptorException e) {
  e.printStackTrace();
}

try {
  cryptorStream.write(b);
  cryptorStream.flush();
  cryptorStream.close();
} catch (IOException e1) {
  e1.printStackTrace();
}

byte[] encrypted = byteStream.toByteArray();

try {
  data = cryptor.decryptData(encrypted, password.toCharArray());
} catch (InvalidHMACException e) {
  e.printStackTrace();
} catch (CryptorException e) {
  e.printStackTrace();
}

if (data != null) {
  Toast.makeText(getApplicationContext(), "data is ok",
      Toast.LENGTH_SHORT).show();

  Bitmap mBitmap = BitmapFactory
      .decodeByteArray(data, 0, data.length);

  new SavePhotoTask().execute(data);

                    ///////// here is a problem! mBitmap is always null.
  if(mBitmap == null){
    Toast.makeText(getApplicationContext(), "bitmap is null!",
        Toast.LENGTH_SHORT).show();
  }

  BitmapDrawable bDrawable = new BitmapDrawable(res, mBitmap);
  img.setBackgroundDrawable(bDrawable);
} else {
  Toast.makeText(getApplicationContext(), "data is null",
      Toast.LENGTH_SHORT).show();
}

Reusing instance

Me and my friend were developing application where we wanted to use this library. Several days ago my friend reported me that reusing instance will cause "HMACMismatch" (Issue on iOS

In my project I am keeping only one instance (using singletoon) and I haven't tested it yet...
My question is, should I create new instance for each decryption/encryption? Or I can leave one instance for whole application runtime?

Thanks in advance

Remove dependency on commons-io

The commons-io dependency is barely utilised. The methods used can be subsumed into this project and the dependency dropped.

Decrypt remote file and save it on external storage

Hello, this is not really an issue with the library but I need some help with an android app that im working on. I'm getting a remote file, getting the input stream, decoding it and saving it to a file. The issue here is tha I cannot open the file - so I guess that the decoding is not right. Can someone of you guys help me?

Here is my code:

new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
Log.d(TAG, "starting");

            JNCryptor cryptor = new AES256JNCryptor();

            try {
                URL url = new URL(FILE_URL);
                URLConnection conection = url.openConnection();
                conection.connect();

                // this will be useful so that you can show a tipical 0-100%
                // progress bar

                // download the file
                InputStream input = new BufferedInputStream(url.openStream(),
                        8192);

                //decrypt istream
                byte[] b = null;
                byte[] data = null;
                try {
                    b = new byte[input.available()];
                    input.read(b);
                } catch (IOException e) {
                    Log.i("decrypt error", e.toString());
                }

                AES256JNCryptorOutputStream cryptorStream = null;

                ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
                Log.d(TAG, "test b " + b.length + " | " + byteStream.size());
                try {
                    cryptorStream = new AES256JNCryptorOutputStream(byteStream,
                            PASS.toCharArray());

                } catch (CryptorException e) {
                    e.printStackTrace();
                }

                try {
                    cryptorStream.write(b);
                    cryptorStream.flush();
                    cryptorStream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }

                byte[] encrypted = byteStream.toByteArray();

                Log.d(TAG, "test encrypted=" + encrypted + " | " + byteStream.size()+" | "+encrypted.length);

                try {
                    data = cryptor.decryptData(encrypted, PASS.toCharArray());
                    Log.d(TAG, "decrypted");
                } catch (InvalidHMACException e) {
                    e.printStackTrace();
                    Log.d(TAG, "error");
                } catch (CryptorException e) {
                    e.printStackTrace();
                    Log.d(TAG, "error 2");
                }

                if (data != null) {
                    Log.d(TAG, "data is ok");
                }

                //end decryption

                // Output stream
                //test
                FileOutputStream fos = new FileOutputStream(Environment
                        .getExternalStorageDirectory().toString()
                        + "/temp.zip");
                fos.write(data);
                fos.close();
                Log.d(TAG, "file saved ");

                input.close();
                Log.d(TAG, "done");
            } catch (Exception e) {
                Log.d(TAG, "Error: " + e.getMessage());
            }
            return null;
        }

AES256JNCryptorInputStream read anomaly

I have been using the AES256JNCryptorInputStream on a file of about 4.5MB. When I buffer it into a FileOutputStream on various blocksizes it does or doesn't decrypt, throwing an invalid HMAC error. I am quite prepared to understand that the problem lies with my implementation - I am afraid it isn't particularly elegant as I have pulled it out of the methods I am using already, but using different values of blockSize will illustrate the issue (16383, 16384 throw an anomalous error, 16385, 5000 work):

public static void  deStream(File fIn, File fOut, int blockSize, char[] pwd) 
throws IOException {
    InputStream fis = new FileInputStream(fIn);
    InputStream AESinStream = new AES256JNCryptorInputStream(fis, pwd);
    FileOutputStream fos = new FileOutputStream(fOut);
    String TAG = "deStream";

    int total = 0;
    try{
        byte[] buffer = new byte[blockSize];
        int i;
        while ((i = AESinStream.read(buffer)) != -1) {
            total += i;
            Log.d(TAG, "read " + i + " of " + total);
            fos.write(buffer, 0, i);
        }
    } catch (Exception e){
        e.printStackTrace();
    } finally {
        Log.d(TAG,"read " + total);
        fos.close();
    }
}

Caused by: org.cryptonode.jncryptor.CryptorException: Unrecognised version number: -119.

`JNCryptor cryptor = new AES256JNCryptor();

        InputStream inputStream = new FileInputStream(inputFile);

        OutputStream outputStream = new FileOutputStream(outputFile);

        byte[] b = imageToByte(inputFile);

        AES256JNCryptorInputStream acis = new AES256JNCryptorInputStream(inputStream, key.toCharArray());
        acis.read(b);

        inputStream.close();
        acis.close();

        byte[] decryptedData = cryptor.decryptData(b, key.toCharArray());`

Caused by: org.cryptonode.jncryptor.CryptorException: Unrecognised version number: -119.
at org.cryptonode.jncryptor.AES256JNCryptor.decryptData(AES256JNCryptor.java:283)

How to deal with AES256JNCryptorInputStream?

Are there any docs how to deal with AES256JNCryptorInputStream?
My task is to decrypt a whole file on the filesystem and i thought, this stream could maybe help here ...

Any hints are appreciated. Thanks!

Videos encrypted in swift RNCryptor cannot be decrypted using JNCryptor

We were looking to decrypt video files in our backend using JNCryptor that was encrypted by our iOS app earlier(using swift RNCryptor), but we get the following error.

org.cryptonode.jncryptor.CryptorException: Unrecognised version number : 12

Tried troubleshooting around a bit, and found it is possible to decrypt video files using JNCryptor that was encrypted by JNCryptor, it is also possible to decrypt files using the swift RNCryptor that was encrypted by JNCryptor.

I wonder if it is a version issue since the swift RNCryptor is at version 5, but JNCryptor is still at 1.2

JNCryptor - RNCryptor Image file encryption / decryption

//Encrypt file
/**
 *
var encryptedData = RNCryptor.encrypt(data: data as Data, withPassword: hashKey.description)
try encryptedData.write(to: fileURL)
 * */
fun encryptFile( inputFile : File ) : File {

    val size = inputFile.length().toInt()
    val fileBytes = ByteArray(size)
    val aeS256JNCryptor = AES256JNCryptor()
    val file = File(Environment.getExternalStorageDirectory().toString() + "/Encrypted_" + inputFile.name)
    try {
        val buf = BufferedInputStream(FileInputStream(inputFile))
        buf.read(fileBytes, 0, fileBytes.size)

        val encryptedFileBytes = aeS256JNCryptor.encryptData(fileBytes, "master".toCharArray())

        val bufOut = BufferedOutputStream(FileOutputStream(file))
        bufOut.write(encryptedFileBytes)

        buf.close()
        bufOut.close()

    } catch (e: FileNotFoundException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    } catch (e: IOException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    }

    return file

}

//Decrypt file
/**
 *
let encryptedData = fileManager.contents(atPath: filePathNormal)
let decryptedData = try RNCryptor.decrypt(data: encryptedData!, withPassword: hashKey.description)
let selected_image = UIImage.sd_image(with: decryptedData)
 * */
fun decryptFile( inputFile : File ) : File {

    val size = inputFile.length().toInt()
    val fileBytes = ByteArray(size)
    val aeS256JNCryptor = AES256JNCryptor()
    val file = File(Environment.getExternalStorageDirectory().toString() + "/Decrypted_" + inputFile.name)
    try {
        val buf = BufferedInputStream(FileInputStream(inputFile))
        buf.read(fileBytes, 0, fileBytes.size)

        val decryptedFileBytes = aeS256JNCryptor.decryptData(fileBytes, "master".toCharArray())

        val bufOut = BufferedOutputStream(file.outputStream())
        bufOut.write(decryptedFileBytes)

        buf.close()
        bufOut.close()

    } catch (e: FileNotFoundException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    } catch (e: IOException) {
        // TODO Auto-generated catch block
        e.printStackTrace()
    }

    return file
}

I am using the above code to encrypt / decrypt files. As of now I am trying to encrypt image files [JPG] using the library.

Post decryption I am unable to load / view the image. I have posted relevant iOS code used in the comments. Please let me know if I am going wrong somewhere.

jncryptor.InvalidHMACException: Incorrect HMAC value.

this is the problem about "jncryptor.InvalidHMACException" in android, when i use gson and Base64.decode before the decrypt:

Gson gson = new Gson();
AES256JNCryptor aes256JNCryptor = new AES256JNCryptor();
String string = gson.toJson(data);
byte[] bytes = Base64.decode(string, 0);

then it throw the exception:

com.ilikelabsapp.MeiFu.frame.utils.jncryptor.InvalidHMACException: Incorrect HMAC value.
com.ilikelabsapp.MeiFu.frame.utils.jncryptor.AES256JNCryptor.decryptV3Data(AES256JNCryptor.java:248)
com.ilikelabsapp.MeiFu.frame.utils.jncryptor.AES256JNCryptor.decryptData(AES256JNCryptor.java:280)
com.ilikelabsapp.MeiFu.frame.entity.EncryptNetworkResponse.getData(EncryptNetworkResponse.java:55)

if only i don't use the base64.decode, then it will throw the exception:

jncryptor.CryptorException: Unrecognised version number: 34.
com.ilikelabsapp.MeiFu.frame.utils.jncryptor.AES256JNCryptor.decryptData(AES256JNCryptor.java:283)
com.ilikelabsapp.MeiFu.frame.entity.EncryptNetworkResponse.getData(EncryptNetworkResponse.java:56)

i don't kow how to slove the InvalidHMACException, did i do anything wrong?
Thank you~

AES128 and JCEUnlimitedPolicy

Is it possible to have something like a 'AES128JNCryptor' class, with AES_128_KEY_SIZE, in the package - so users can use the standard JRE without installing JCEUnlimitedPolicy ? This would be nice, and can be used with some kRNCryptorAES128Settings (with keySize = kCCKeySizeAES128) on the iOS side.

Thansk.

Empty Password

Hi,

I'm currently in the situation that I have a file that was encrypted with an empty password (empty String) and I have to decrypt this with JNCryptor. This seems not to be possible since JNCryptor has a dedicated check on empty password to not allow this.

Is there any way to pass or override this check and decrypt an input that was encrypted with empty password?

Thanks!

Not working in Android 2.2

Reported by benoffi7, May 22, 2013

05-22 12:31:06.577: W/System.err(12154): org.cryptonode.jncryptor.CryptorException: Failed to generate key from password using PBKDF2WithHmacSHA1.
05-22 12:31:06.577: W/System.err(12154):    at org.cryptonode.jncryptor.AES256v2Cryptor.keyForPassword(AES256v2Cryptor.java:114)
05-22 12:31:06.577: W/System.err(12154):    at org.cryptonode.jncryptor.AES256v2Cryptor.encryptData(AES256v2Cryptor.java:198)
05-22 12:31:06.577: W/System.err(12154):    at org.cryptonode.jncryptor.AES256v2Cryptor.encryptData(AES256v2Cryptor.java:229)
05-22 12:31:06.587: W/System.err(12154): Caused by: java.security.NoSuchAlgorithmException: SecretKeyFactory PBKDF2WithHmacSHA1 implementation not found
05-22 12:31:06.587: W/System.err(12154):    at org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:105)
05-22 12:31:06.587: W/System.err(12154):    at javax.crypto.SecretKeyFactory.getInstance(SecretKeyFactory.java:111)
05-22 12:31:06.587: W/System.err(12154):    at org.cryptonode.jncryptor.AES256v2Cryptor.keyForPassword(AES256v2Cryptor.java:108)

Thanks!

encryption of data on objective-c does not match encryption of the same data in the server

I don't know if it is me but here is the issue. I am encrypting data on iOS7 using + (NSData )encryptData:(NSData *)thePlaintext withSettings:(RNCryptorSettings)theSettings password:(NSString *)aPassword error:(NSError *)anError; which takes a password and settings (I suspect that my problem lies right here with the settings) then I make a string a base64 method. Then I send to the server the original data (not the encrypted data) and the string. What I want to do is to encrypt the data and use Base64 to construct a string. That all works fine but the strings don't match. I think that the problems is that the encryption with password in JNCryptor does not take settings parameter and that the settings vary even though I didn't make changes to the settings constant provided.

Does any one know how to make sure I'm using the same settings? I'm using the sbt artifact since I'm on Play framework.

Security issue on Android < 4.4

See http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html

Since this library appears to be directly using numbers from a default-initialized SecureRandom, it should not be used on Android versions below 4.4 without a separate intialization step.

Either the fix should be applied in the code here where applicable (via reflection, probably, to avoid borking non-Android environments), or there should be a big disclaimer and a minimum Android recommendation of 4.4 rather than 2.3.3 for using this library.

Illegal key size in Play Framework with java 1.7.0_45

I tried to integrate JNCryptor in Play Framework 2.2 application but I get following exception

org.cryptonode.jncryptor.CryptorException: Caught InvalidKeyException. Do you have unlimited strength jurisdiction files installed?
    at org.cryptonode.jncryptor.AES256JNCryptor.encryptData(AES256JNCryptor.java:334)
    at org.cryptonode.jncryptor.AES256JNCryptor.encryptData(AES256JNCryptor.java:353)
    at controllers.Application.crypto(Application.java:24)
    at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:61)
    at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:61)
    at play.core.Router$HandlerInvoker$$anon$7$$anon$2.invocation(Router.scala:183)
    at play.core.Router$Routes$$anon$1.invocation(Router.scala:377)
    at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:56)
    at play.core.j.JavaAction$$anon$3.apply(JavaAction.scala:91)
    at play.core.j.JavaAction$$anon$3.apply(JavaAction.scala:90)
    at play.core.j.FPromiseHelper$$anonfun$flatMap$1.apply(FPromiseHelper.scala:82)
    at play.core.j.FPromiseHelper$$anonfun$flatMap$1.apply(FPromiseHelper.scala:82)
    at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:278)
    at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:274)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:29)
    at play.core.j.HttpExecutionContext$$anon$2.run(HttpExecutionContext.scala:37)
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:42)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.security.InvalidKeyException: Illegal key size
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1024)
    at javax.crypto.Cipher.implInit(Cipher.java:790)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
    at javax.crypto.Cipher.init(Cipher.java:1348)
    at javax.crypto.Cipher.init(Cipher.java:1282)
    at org.cryptonode.jncryptor.AES256JNCryptor.encryptData(AES256JNCryptor.java:321)
    ... 21 more

I use Oracle's 1.7.0 JDK on OS X system. I used exactly your example, so my Application.java file looks like this:

package controllers;

import play.Logger;
import play.mvc.*;
import views.html.*;

import org.cryptonode.jncryptor.*;

public class Application extends Controller {

    public static Result index() {
        return ok(index.render("Your new application is ready."));
    }

    public static Result crypto() {

        JNCryptor cryptor = new AES256JNCryptor();
        byte[] plaintext = "Hello, World!".getBytes();
        String password = "secretsquirrel";

        Logger.debug("password length: " + password.toCharArray().length + "\n");

        try {
            byte[] ciphertext = cryptor.encryptData(plaintext, password.toCharArray());
            return ok(new String(ciphertext));
        } catch (CryptorException e) {
            e.printStackTrace();
        }

        return ok("Not encrypted :(");
    }

}

Did anyone try to integrate JNCryptor with Play Framework and Java 1.7 and had similar issue?

Unrecognised version number using Android 4.4 SDK

I got an CryptorException by using this code:

JNCryptor cryptor = new AES256JNCryptor();
byte[] encryptedText = response_string.getBytes();
String password = "an16bytelongkey!an16bytelongkey!";

try {
    byte[] plaintext = cryptor.decryptData(encryptedText, password.toCharArray());
} catch (InvalidHMACException e1) {
    e1.printStackTrace();
    return;
} catch (org.cryptonode.jncryptor.CryptorException e1) {
    e1.printStackTrace();
    return;
}

response_string is a json string encrypted by RNCryptor in PHP.
the same code using Objective-C works.

(Full error: W/System.err﹕ org.cryptonode.jncryptor.CryptorException: Unrecognised version number: 65.)

"Unknown header" error when decrypting with RNCryptor

Hi. I encrypt data using JNCryptor (lasted version), but when I use RNCryptor (lasted version) to decrypt encrypted data on IOS, I get this error: net.robnapier.RNCryptManager Code=2 Unknown header.
What is wrong with this? Please help me, thanks.

org.cryptonode.jncryptor.CryptorException: Unrecognised version number: 83

I am using below code for descryption and it is giving me " org.cryptonode.jncryptor.CryptorException: Unrecognised version number: 83" error.

/***

  • Method to Decrypt

  • @return

  • @throws CryptorException

  • @throws UnsupportedEncodingException
    */
    public String decryptData(String data) throws CryptorException, UnsupportedEncodingException {
    String password = "LSC@SD2017@ps";

    JNCryptor cryptor = new AES256JNCryptor();
    byte[] decode = Base64.decode(data,Base64.NO_WRAP);

    byte[] decrypted = cryptor.decryptData(decode, password.toCharArray());

    String s = new String( decrypted ,"UTF-8");
    return s;
    }

This is the string to be decrypted: Log.e("tag", decryptData( "U2FsdGVkX18x4uksV5otdPk2cc4Cj6UjNoYmSI7iKD00FMyK4KuGkpIw1uBgCkGF2dbE0ye1QjUaFo3BNv1Yr4CTqoSCB03lojmc++PJ+1VCZqXbqFzNMuAhCxWfKft/w+QgFbGf4sXKtDI/ky9AnxzDQTRdIuglPm+xS3CGj8MaWdBSghS4G98rFsDXOnKrfv4/ax0HkUZc7vrqUideUjd/nxBvNnG1qQd3EpFGOKuFVzmUrq89nSVrjcmKFJFLe5XVTf/MK8ofH8EPxepjKQgAycU8a839tB0Hl6djcVCFfNFqPLIp9pGwmF0iDEhWSQNI1y6bjV8AjO+Ggqp1Kw=="));

Performance Issues on Android

So I am trying to use this for android and it works but the performance is terrible. It takes several seconds to decrypt an asset I have.

For instance, I have images as low as 50KB to 150KB so nothing too large. But whenever I try to decrypt them, it takes several seconds for them to process. I use this for iOS and it's nearly instantaneous. Would anyone have any suggestions? The function I am using for this process is below...

public byte[] decryptInputStream(InputStream in){
if(in == null)
return null;

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int i = Integer.MAX_VALUE;
    try{
        while((i = in.read(buffer, 0, buffer.length)) > 0)
            outputStream.write(buffer, 0, i);
    }
    catch(Exception e){

    }
    try {
        byte[] decrpytedStream = decryptor.decryptData(outputStream.toByteArray(), KEY.toCharArray());
        return decrpytedStream;
    }
    catch(CryptorException e){
        Log.e("AES Cryptor", "Input Stream Decryption Error");
    }
    return null;
}

Android 4.1 - java.lang.NoClassDefFoundError

On Android 4.1 and below, I can't seem to use the JNCryptor library. I get errors like this one below:

  05-06 19:35:47.453  27664-27664/? I/dalvikvm﹕ Could not find method org.cryptonode.jncryptor.Validate.notNull, referenced from method org.cryptonode.jncryptor.AES256JNCryptorOutputStream.<init>
  05-06 19:35:47.453  27664-27664/? W/dalvikvm﹕ VFY: unable to resolve static method 60559: Lorg/cryptonode/jncryptor/Validate;.notNull (Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V
  05-06 19:35:47.453  27664-27664/? D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x0008
  05-06 19:35:47.453  27664-27664/? I/dalvikvm﹕ Could not find method org.cryptonode.jncryptor.Validate.notNull, referenced from method org.cryptonode.jncryptor.AES256JNCryptorOutputStream.<init>
  05-06 19:35:47.453  27664-27664/? W/dalvikvm﹕ VFY: unable to resolve static method 60559: Lorg/cryptonode/jncryptor/Validate;.notNull (Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V
  05-06 19:35:47.453  27664-27664/? D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x000b
  05-06 19:35:47.453  27664-27664/? E/dalvikvm﹕ Could not find class 'org.cryptonode.jncryptor.AES256JNCryptorOutputStream$MacOutputStream', referenced from method org.cryptonode.jncryptor.AES256JNCryptorOutputStream.createStreams
  05-06 19:35:47.453  27664-27664/? W/dalvikvm﹕ VFY: unable to resolve new-instance 8174 (Lorg/cryptonode/jncryptor/AES256JNCryptorOutputStream$MacOutputStream;) in Lorg/cryptonode/jncryptor/AES256JNCryptorOutputStream;
  05-06 19:35:47.453  27664-27664/? D/dalvikvm﹕ VFY: replacing opcode 0x22 at 0x001a
  05-06 19:35:47.469  27664-27664/? I/dalvikvm﹕ Could not find method org.cryptonode.jncryptor.AES256JNCryptorOutputStream$MacOutputStream.write, referenced from method org.cryptonode.jncryptor.AES256JNCryptorOutputStream.writeHeader
  05-06 19:35:47.469  27664-27664/? W/dalvikvm﹕ VFY: unable to resolve virtual method 60507: Lorg/cryptonode/jncryptor/AES256JNCryptorOutputStream$MacOutputStream;.write (I)V
  05-06 19:35:47.469  27664-27664/? D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0007
  05-06 19:35:47.469  27664-27664/? I/dalvikvm﹕ Could not find method org.cryptonode.jncryptor.AES256JNCryptorOutputStream$MacOutputStream.write, referenced from method org.cryptonode.jncryptor.AES256JNCryptorOutputStream.writeHeader
  05-06 19:35:47.469  27664-27664/? W/dalvikvm﹕ VFY: unable to resolve virtual method 60507: Lorg/cryptonode/jncryptor/AES256JNCryptorOutputStream$MacOutputStream;.write (I)V
  05-06 19:35:47.469  27664-27664/? D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0028
  05-06 19:35:47.469  27664-27664/? D/dalvikvm﹕ DexOpt: unable to opt direct call 0xec5a at 0x1c in Lorg/cryptonode/jncryptor/AES256JNCryptorOutputStream;.createStreams
  05-06 19:35:47.469  27664-27664/? D/AndroidRuntime﹕ Shutting down VM
  05-06 19:35:47.469  27664-27664/? W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xa622b288)
  05-06 19:35:47.469  27664-27664/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
      java.lang.NoClassDefFoundError: org.cryptonode.jncryptor.Validate
              at org.cryptonode.jncryptor.AES256JNCryptorOutputStream.<init>(AES256JNCryptorOutputStream.java:57)
              at br.com.estudio89.rhmais.core.CustomApplication.onCreate(CustomApplication.java:29)
              at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:999)
              at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4151)
              at android.app.ActivityThread.access$1300(ActivityThread.java:130)
              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1255)
              at android.os.Handler.dispatchMessage(Handler.java:99)
              at android.os.Looper.loop(Looper.java:137)
              at android.app.ActivityThread.main(ActivityThread.java:4745)
              at java.lang.reflect.Method.invokeNative(Native Method)
              at java.lang.reflect.Method.invoke(Method.java:511)
              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
              at dalvik.system.NativeStart.main(Native Method)

I noticed that the NoClassDefFoundError only happens with classes that are private to the library, I don't know if Android has any problem with this. I ran the exact same code on Android 5.0+ and it works perfectly.

If anyone would give me a hand with this I would greatly appreciate it, as I have been struggling with this for a couple days and I ran out of ideas of what to do.

Thanks

null CryptorException

Hi, I'm trying to make a static class for my singleton that can encrypt or decrypt strings from anywhere in my application. Here's my code for the class that I initialize in my singleton

public class BluetoothCrypto {
    static JNCryptor cryptor;
    static String password;

    public BluetoothCrypto(){
        cryptor = new AES256JNCryptor();
    }

    public BluetoothCrypto(String password){
        cryptor = new AES256JNCryptor();
        BluetoothCrypto.password = password;
    }

    public static void setPassword(String password){
        BluetoothCrypto.password = password;
    }

    public static byte[] encrypt(String plainstring){
        byte[] plaintext = plainstring.getBytes();      
        return (encrypt(plaintext));
    }

    public static byte[] encrypt(byte[] plaintext){
        try {
          byte[] ciphertext = cryptor.encryptData(plaintext, password.toCharArray());
          return ciphertext;
        } catch (CryptorException e) {
          // Something went wrong
          e.printStackTrace();
        }
        return null;
    }

    public static String decrypt(byte[] ciphertext){
        try {
            byte[] plaintext = cryptor.decryptData(ciphertext, password.toCharArray());
            String plainstring = new String(plaintext);
            return plainstring;
        } catch (CryptorException e) {
            Log.wtf("decrypt", e.getMessage());
        }
        return null;
    }
}

it seems to encrypt fine, but trying to decrypt throws a null CryptorException. needless to say this is kind of confusing for debugging purposes. do you know what could be causing it?

Change from stock settings works in ObjC, but I may have screwed myself attempting a Java version.

I basically am using this object for my ObjC settings:

static const RNCryptorSettings kOCCryptorAES256Settings = {
    .algorithm = kCCAlgorithmAES128,
    .blockSize = kCCBlockSizeAES128,
    .IVSize = kCCBlockSizeAES128,
    .options = kCCOptionPKCS7Padding,
    .HMACAlgorithm = kCCHmacAlgSHA256,
    .HMACLength = CC_SHA256_DIGEST_LENGTH,

    .keySettings = {
        .keySize = kCCKeySizeAES256,
        .saltSize = 8,
        .PBKDFAlgorithm = kCCPBKDF2,
        .PRF = kCCPRFHmacAlgSHA512,
        .rounds = kOCDefaultIterations
    },

    .HMACKeySettings = {
        .keySize = kCCKeySizeAES256,
        .saltSize = 8,
        .PBKDFAlgorithm = kCCPBKDF2,
        .PRF = kCCPRFHmacAlgSHA512,
        .rounds = kOCDefaultIterations
    }
};

The problem is, the PRF of SHA512 for the keys is not in the JNCryptor implementation. Do you know of any way to implement this in Java? My first goal would be to fork your codebase and attempt on top, but I'm getting absolutely nowhere right now, and I'd like very much not to rewrite. My question boils down to this: changing the settings was very easy in the ObjC implementation, but the Java one seems very rigid. Is there a reason for this in the language instead of being an implementation detail from your side?

Android no method equivalent to iOS implementation

Hey,

I used an encryption on the iOS side, but I can't create the equivalent in Android, because I can't find an equivalent public method to the following

- (RNEncryptor *)initWithSettings:(RNCryptorSettings)settings
                         password:(NSString *)password
                               IV:(NSData *)anIV
                   encryptionSalt:(NSData *)anEncryptionSalt
                         HMACSalt:(NSData *)anHMACSalt
                          handler:(RNCryptorHandler)handler;

the only method that I found is this one and it's not public

byte[] encryptData(byte[] plaintext, char[] password, byte[] encryptionSalt,
      byte[] hmacSalt, byte[] iv) throws CryptorException {}

The problem is that I need to pass my own encryptionSalt, hmacSalt and iv, but I can't with this method, because it generate random data

public byte[] encryptData(byte[] plaintext, char[] password)
      throws CryptorException {

    byte[] encryptionSalt = getSecureRandomData(SALT_LENGTH);
    byte[] hmacSalt = getSecureRandomData(SALT_LENGTH);
    byte[] iv = getSecureRandomData(AES_BLOCK_SIZE);

    return encryptData(plaintext, password, encryptionSalt, hmacSalt, iv);
  }

Am I doing something wrong?

org.cryptonode.jncryptor.CryptorException: Unrecognised version number: 83

I am using below code for descryption and it is giving me " org.cryptonode.jncryptor.CryptorException: Unrecognised version number: 83" error.

/***
* Method to Decrypt
* @return
* @throws CryptorException
* @throws UnsupportedEncodingException
*/
public String decryptData(String data) throws CryptorException, UnsupportedEncodingException {
String password = "LSC@SD2017@ps";

    JNCryptor cryptor = new AES256JNCryptor();
    byte[] decode =   Base64.decode(data,Base64.NO_WRAP);

    byte[] decrypted = cryptor.decryptData(decode, password.toCharArray());

    String s = new String( decrypted ,"UTF-8");
    return s;
}

This is the string to be decrypted: Log.e("tag", decryptData( "U2FsdGVkX18x4uksV5otdPk2cc4Cj6UjNoYmSI7iKD00FMyK4KuGkpIw1uBgCkGF2dbE0ye1QjUaFo3BNv1Yr4CTqoSCB03lojmc++PJ+1VCZqXbqFzNMuAhCxWfKft/w+QgFbGf4sXKtDI/ky9AnxzDQTRdIuglPm+xS3CGj8MaWdBSghS4G98rFsDXOnKrfv4/ax0HkUZc7vrqUideUjd/nxBvNnG1qQd3EpFGOKuFVzmUrq89nSVrjcmKFJFLe5XVTf/MK8ofH8EPxepjKQgAycU8a839tB0Hl6djcVCFfNFqPLIp9pGwmF0iDEhWSQNI1y6bjV8AjO+Ggqp1Kw=="));

Unable to get the decryptData method to work correctly; can you provide an example?

I tried the simple example on the GitHub JNCryptor page and it seemed to work OK. However, the example only shows the use of encryptData; I also wanted to try decryptData, so I modified the example to look like this:

byte[] encrypted = cryptor.encryptData(plaintext, password.toCharArray()); System.out.println("Encrypted text: " + encrypted.toString()); byte[] decrypted = cryptor.decryptData(encrypted, password.toCharArray()); System.out.println("Encrypted text back to plain text: " + decrypted.toString());

However, it didn't work correctly:
Encrypted text: [B@2cfb4a64
Encrypted text back to plain text: [B@5474c6c

I expected to get the original text back ("Hell,o world!").

What did I do wrong?

Using decription method runs too slow

Hi,

Thanks for this awesome tool,

Currently we are using the RNCryptor in Objective-C, Java and Php.
Both Objective-C and Php calculations are too fast but Decrypt function in Java runs so slowly and it takes about 5 secs on HTC Desire HD Android 4.0.3.

Where the problem is?

Appreciate any help,

Cheers,

decrypt issue on Android

I have a problem with decrypt on Android. Basically I'm trying to decrypt the encrypted response which comes from web service (python) and it's encrypted with RNCryptor. When I'm trying to decrypt it, I always get the following error.
Unrecognised version number: -45.

The encrypted response from server is the following.
0301be65c81525dd2e9ea320f0e40dad2feba53d15cd1f9bfb8260a7a28f80501b184a536a24143a03c4edec2851d746f51098ca85f7b3de37c88bfe19814ef965baa3c50737749aef2c839466f573c6af43b1a232d94898396648827890b49c2c24f2fa1e7d43f8050207fada647924eccf

In iOS, decrypt is working fine.
Actually I'm using the following code to decrypt the response.

    private String decryptID(String encryptID) {
            String password = "X5vNjxL0Nh2rythdE1ra";
            JNCryptor cryptor = new AES256JNCryptor();

            try {
                byte[] b;
                b = Base64.decode(encryptID, 0);

                byte[] plainText = cryptor.decryptData(b, password.toCharArray());
                return new String(plainText);
            } catch (CryptorException e) {
                // Something went wrong
                e.printStackTrace();

                return "0";
            }
        }

Please help to figure out the issue.

Ensure MAC calculations are resistant to timing attacks

Currently, MAC byte array values are compared using standard library methods that will return as soon as a result is calculated. Instead, there should be a more laborious check that tests each byte regardless of whether a result is already known. This will prevent timing attacks.

Android and iOS compatibility issue

The encryptor produces a byte array, that when encoded using Base64, produces a 112 character length string on iOS and 114 character length string on Android. Does this mean that JNCryptor and RNCryptor libraries aren't compatible after all? I noticed that the RNCryptor uses PKCS7Padding and JNCryptor uses PKCS5Padding. Is this the cause? How do I go about fixing this?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.