Git Product home page Git Product logo

java-aes-crypto's Introduction

java-aes-crypto

This AES library is very simple and works only on Android. For a cross-platform encryption system, please use TozStore. It's available for Android, iOS, and JavaScript for the browser, as well as back-end systems like Node, Ruby, Python, Java, and Go.

Java-AES-Crypto is Tozny's simple Android class for encrypting & decrypting strings, aiming to avoid serious cryptographic errors that most such classes suffer from. Show me the code

Features

Here are the features of this class. We believe that these properties are consistent with what a lot of people are looking for when encrypting Strings in Android.

  • Works for strings: It should encrypt arbitrary strings or byte arrays. This means it needs to effectively handle multiple blocks (CBC) and partial blocks (padding). It consistently serializes and deserializes ciphertext, IVs, and key material using base64 to make it easy to store.
  • Algorithm & Mode: We chose: AES 128, CBC, and PKCS5 padding. We would have picked GCM for its built-in integrity checking, but that's only available since Android Jelly Bean.
  • IV Handling: We securely generate a random IV before each encryption and provide a simple class to keep the IV and ciphertext together so they're easy to keep track of and store. We set the IV and then request it back from the Cipher class for compatibility across various Android versions.
  • Key generation: Random key generation with the updated generation code recommended for Android. If you want password-based keys, we provide functions to salt and generate them.
  • Integrity: Lots of people think AES has integrity checking built in. The thinking goes, "if it decrypts correctly, it was generated by the person with the private key". Actually, AES CBC allows an attacker to modify the messages. Therefore, we've also added integrity checking in the form of a SHA 256 hash.
  • Older Phones: It's designed for backward compatibility with older phones, including ciphers that are available for most versions of Android as well as entropy fixes for old Android bugs.

How to include in project?

Copy and paste

It's a single very simple java class, AesCbcWithIntegrity.java that works across most or all versions of Android. The class should be easy to paste into an existing codebase.

Android Library project

The library is in Android library project format so you can clone this project and add as a library module/project.

Maven Dependency

We've also published the library AAR file via Jitpack for simple gradle dependency management:

Add the Jitpack repository to your root build.gradle:

allprojects {
  repositories {
    ...
    maven { url 'https://jitpack.io' }
  }
}

Add the dependency to your project's build.gradle:

dependencies {
  compile 'com.github.tozny:java-aes-crypto:1.1.0'
}

Examples

Generate new key

  AesCbcWithIntegrity.SecretKeys keys = AesCbcWithIntegrity.generateKey();

Generate a key from a password or passphrase

  EXAMPLE_PASSWORD = // Get password from user input
  String salt = saltString(generateSalt());
  // You can store the salt, it's not secret. Don't store the key. Derive from password every time
  Log.i(TAG, "Salt: " + salt);
  key = generateKeyFromPassword(EXAMPLE_PASSWORD, salt);

Encrypt

   AesCbcWithIntegrity.CipherTextIvMac cipherTextIvMac = AesCbcWithIntegrity.encrypt("some test", keys);
   //store or send to server
   String ciphertextString = cipherTextIvMac.toString();

Decrypt

  //Use the constructor to re-create the CipherTextIvMac class from the string:
  CipherTextIvMac cipherTextIvMac = new CipherTextIvMac (cipherTextString);
  String plainText = AesCbcWithIntegrity.decryptString(cipherTextIvMac, keys);

Storing Keys

Once you've generated a random key, you naturally might want to store it. This may work for some use cases, but please be aware that if you store the key in the same place that you store the encrypted data, your solution is not cryptographically sound since the attacker can just get both the key and the encrypted text. Instead, you should use either the Keystore infrastructure or consider generating the key from a passphrase and using that to encrypt the user data.

If despite the above you still want to store the key, you can convert the keys to a string using the included functions and store them in preferences or SQLite.

Note that if you hard-code keys or passphrases, or generate them from a static value, you will likely get an error message from the Android security scanner.

License

The included MIT license is compatible with open source or commercial products. Tozny also offers custom support and licensing terms if your organization has different needs. Contact us at [email protected] for more details.

java-aes-crypto's People

Contributors

austinhaigh avatar jamesjb avatar m4dc4p avatar orhanobut avatar scottyab avatar swenson avatar syntaxpolice 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  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

java-aes-crypto's Issues

Encrypted Stream...

Are there any examples for using this class to encrypt/decrypt a byte stream?

is IV included into the cipher?

Hey Guys, Thanks for doing
that important work. I am
curious are you also including
the IV inside the final cipher
or you pass it some other way ?

Thanks in advance.
Roman

Get error when trying to decrypt String from a ContentProvider

I am currently using your excellent code to encrypt and decrypt on Android, however I have hit an issue that I don't know how to resolve or what might be causing it.

When I use your code straight up where I encode and decode a simple String it works fine.

However what I need to do is encrypt the String, put it in a Content Provider and then decrypt it when I pull it from the Content Provider.

However when I pull it from the ContentProvider and try to decrypt it I get the following exception:

java.security.GeneralSecurityException: MAC stored in civ does not match computed MAC.

The exact same String works if I decrypt it without putting it into the Content Provider so I am unsure why I am getting this issue?

Can you help me find why this might be occurring?

SecureRandom backed by wrong Provider exception

PrngFixes is throwing exception on some devices (collected from crash log) such as

Samsung - GT I9663, GT I9082L, GT S7500, SCH R820
Onda - TM 7043XD
Sony - C5303
Lenovo
and more

Android version: 2.3.4, 2.3.6 | 4.1.1, 4.1.2, 4.2.2

java.lang.SecurityException: new SecureRandom() backed by wrong Provider: class com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes$LinuxPRNGSecureRandomProvider
   at com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes.installLinuxPRNGSecureRandom(AesCbcWithIntegrity.java:764)
   at com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes.apply(AesCbcWithIntegrity.java:684)
   at com.tozny.crypto.android.AesCbcWithIntegrity.fixPrng(AesCbcWithIntegrity.java:347)
   at com.tozny.crypto.android.AesCbcWithIntegrity.generateKeyFromPassword(AesCbcWithIntegrity.java:184)
   at com.tozny.crypto.android.AesCbcWithIntegrity.generateKeyFromPassword(AesCbcWithIntegrity.java:234)

request: java jre/jdk specific version

Would it be possible to get a java specific version of this?

Also it would be worth testing something encrypted on jre could be decrypted from adk and vs versa

Any way to encrypt and decrypt on different devices?

I am encrypting string on one device. I store salt in SQLite on that device. The encrypted text is then passed to another device which obviously has it's own salt stored in it's database and that results into MAC stored in civ does not match computed MAC. exception.

Is there any way to make it work across multiple devices? I could be doing something fundamentally wrong here, or even something this library is not addressing but any guidance would be much appreciated.

TIA.

Users be warned. SHA 256 instead of PBKDF2

The key derivation function in the library is SHA 256. SHA 256 is fast, so deriving the key will be easier than if this library used PBKDF2. This means the encrypted data is extra vulnerable if you have a weak password.

Maven support

It will be great to put this project as jar into the maven central, thus we can use it via dependency and for each update, we can get it immediately at least. Currently we need to copy/paste.

I really like this repo :)

Storing secret key

How do we store the AesCbcWithIntegrity.SecretKeys in the keystore. The keystore api provides the following method: keyStore.setKeyEntry(String, Key, Char[],Certificate[]). How do i convert the SecretKeys construct to Key.

Access from other activity

Hello guys! I've a problem... what if I want to decrypt the string from other activity/fragment/etc?

As far as I can see, I need the CipherTextIvMac and keys, the same ones used for encrypt. Wouldn't be a best option to set a key value, pass it and the encrypted string for decrypt?

That way we can move around the data and keep it safe/secure.

Performance issues with PBKDF2WithHmacSHA1

After profiling my application's startup process I found that this the main contributor to my applications slow startup time was this library. The issue seems to be with the generateKeyFromPassword() method along with specifically usage of the SecretKeyFactory returned from SecretKeyFactory.getInstance(PBE_ALGORITHM). I'm calling generateKeyFromPassword() a few times in our application, but it seems to be adding seconds to the startup time.

Is there an alternative algorithm that can be used that would significantly increase performance? I'm aware a migration would likely have to take place.

Where should I store the salt?

Hello, thanks for a great library!

Im encrypting some data using an autogenerated password stored (for each user) on a server.
When I want to decrypt the data I then recreate the key with salt generated from java-aes-crypto. I am currently storing the salt in the SharedPreferences on the cellphone but this seems wrong since a potential hacker could easily access it if the phone is rooted.

Where should I store the salt?

Support for GCM chiper transformation

While using this class, if Android <4.4 is not on plate, would it be a legit (and sensible) choice to replace AES/CBC/PKCS5Padding with AES/GCM/NoPadding? Is it a redundant option, due to the integrity checking you added?
If it makes sense, are there other changes required in order to optimize the class, aside from reducing the IV length to 12 bytes?
Any suggestion is welcome
Thanks

Allow some params to be editable

I'm thinking of specifically AES_KEY_LENGTH_BITS and PBE_ITERATION_COUNT; we would like to set these to 256 and 20_000 respectively. Of course we can just copy/paste the file into our build, but it would be nice to be able to import it in directly.

Security alert on our production app on google play console

Hi,

We are seeing a warning on our production app on google play console. The warning states:

Security alert
Your app contains unsafe cryptographic encryption patterns. Please see this Google Help Center article for details.
Vulnerable classes: com.xxx.xxx.android.AesCbcWithIntegrity
Affects APK version 10819.

The article the warning is referring to https://support.google.com/faqs/answer/9450925

Remediation
for Unsafe Cryptographic Encryption - Google HelpThis information is intended for developers with app(s) that contain unsafe cryptographic encryption patterns. That is, a ciphertext is generated with a statically computed secret key, salt, or initiasupport.google.com

Can someone help me to resolve this Security alert warning?

Add feature to store keys in Java Keystore (JKS) / Android Keystore (AKS)

Hi, this library looks very nice (unlike the native API), but I have some trouble storing the resulting keys.

I tried to store the keys in AndroidKeyStore for its hardware-backed security, but I am getting an exception saying I cannot store secretKeys at all. Is there a way how to achieve this?

Thanks.

keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);

AesCbcWithIntegrity.SecretKeys keys = AesCbcWithIntegrity.generateKey();
KeyStore.SecretKeyEntry entryConfidential = new KeyStore.SecretKeyEntry(keys.getConfidentialityKey());
keyStore.setEntry(confidentialAlias, entryConfidential, null); //throws exception

this ↑ throws an exception java.security.KeyStoreException: Entry must be a PrivateKeyEntry or TrustedCertificateEntry; was SecretKeyEntry: algorithm - AES

Question about license and using strong encryption outside of USA

I am working on a Android application that i want to release to be available for customers from both USA and Romania. Does this library require a special license for using strong encryption? The reason why i ask this is because some other libraries like SQLCIpher for Android require special license for this ( according to this blog http://www.informit.com/articles/article.aspx?p=2268753&seqNum=3 )

I was wondering if this is the case for this too. Please let me know. Thank you very much.

Caller-provided IV not permitted

I am trying to use AES with GCM No padding. I am getting this exception Caller-provided IV not permitted in encryption

I am using GCMParamSepc for IV. Can you please help me fix that?

MAC stores in civ does not match computed MAC

Hello guys! Thanks for the awesome library. I am running into an issue with decrypting a string that is stored in Preferences.

So what I am doing is generating a key based on a password and storing the salt. I regenerate the key whenever I need access to it. What I am trying to do those is decrypt the encrypted string without the CiperTextIvMac available.

So an example:

I get plain text -> encrypt it -> store on shared preferences.
Open app up a later time after it has been completely closed -> retrieve encrypted string from preferences -> decrypt string -> get plain text.

But what happens when I try to decrypt is

java.security.GeneralSecurityException: MAC stored in civ does not match computed MAC.
10-21 10:54:40.084  15146-15146/app_android W/System.err﹕ at app_android.security.AesCbcWithIntegrity.decrypt(AesCbcWithIntegrity.java:368)
10-21 10:54:40.084  15146-15146/app_android W/System.err﹕ at app_android.security.AesCbcWithIntegrity.decryptString(AesCbcWithIntegrity.java:331)
10-21 10:54:40.084  15146-15146/app_android W/System.err﹕ at app_android.security.AesCbcWithIntegrity.decryptString(AesCbcWithIntegrity.java:346)

Here is my code to decrypt:

String salt = getSalt();
AesCbcWithIntegrity.SecretKeys keys =   AesCbcWithIntegrity.generateKeyFromPassword(Constants.KEY, salt);
decryptedUsername = AesCbcWithIntegrity.decryptString(new   AesCbcWithIntegrity.CipherTextIvMac(username), keys);

Not sure if I am missing something obvious. But thanks for the help.

aes-crypto missing from Maven Central

Added mavenCentral() to the build.gradle file and added the dependency to app/build.gradle, but aes-crypto is not available. Tried "0.0.1", "0.+", and "1.+" (to match your most recent release).

constantTimeEq not constant

Hi, the constantTimeEq starts with:

if (a.length != b.length) {
return false;
}

this kind of makes it not equal time or am I missing something?

If I remember correctly, the correct way to handle this is with fake comparissons, something like:

int result = 0;
if (a.length != b.length) {
for (int i = 0; i < a.length; i++) {
result |= a[i] ^ a[i];
}
return false;
}

LG devices Bad base64

for some reason this works on all other devices I tested on, samsung, nexus, motorola, etc... but when I went to test on multiple LG G4 I get a build fail with a java.lang.IllegalArgumentException: bad base-64

Build.SERIAL is deprecated in SDK 26 and will return UNKNOWN

Referencing this code

String deviceSerial = (String) Build.class.getField("SERIAL").get(
null);
Since SDK 26, Build.SERIAL is deprecated and will NOT return the device's serial number. This makes it will make it non-compatible. Since SDK 26 one should use Build.getSerial() which requires the PHONE permission.

https://developer.android.com/reference/android/os/Build.html#getSerial()

This will probably make the encrypted data non forward compatible when a device is upgraded to SDK 26.

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.