Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migration to Play 2.5.3 - Crypto library deprecated but also perhaps broken?

Currently receiving this error while trying to move an application to 2.5.3

Error injecting constructor, java.lang.RuntimeException: The global crypto instance requires a running application!

Am wading through close to 1000 errors (reported so far - once I clear a batch then low and behold yet another batch show up so there could be lots more)

I can't seem to get a handle on how to fix this particular one however. The migration guide indicates that the library is deprecated and will be removed and offers replacement paths -- none of which appear trivial -- but it doesn't indicate how to get the library instantiated with the need for the running Application.

Did find some chatter in github issues but nothing specific to the actual problem.

All I need (right now) is Crypto.encryptAES and Crypto.decryptAES replacements if the library can't be properly started if a quick sub is possible.

This problem currently stops Play dead in it's tracks btw so I have no idea what comes next once I get past this issue.

DI would supposedly handle this and yet it obviously doesn't.

Here is relevant portion of stack trace I'm seeing:

1 error at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025) at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051) at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:405) at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:400) at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:123) at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:158) at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:155) at play.utils.Threads$.withContextClassLoader(Threads.scala:21) at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:155) ... 15 common frames omitted Caused by: java.lang.RuntimeException: The global crypto instance requires a running application! at scala.sys.package$.error(package.scala:27) at play.api.libs.Crypto$$anonfun$crypto$1.apply(Crypto.scala:56) at play.api.libs.Crypto$$anonfun$crypto$1.apply(Crypto.scala:56) at scala.Option.fold(Option.scala:158) at play.api.libs.Crypto$.crypto(Crypto.scala:57) at play.api.libs.Crypto$.encryptAES(Crypto.scala:78)

I used that to find this: https://github.com/playframework/playframework/blob/2.5.3/framework/src/play/src/main/scala/play/api/libs/Crypto.scala in the hopes that it might shed some light but I'm still at a loss as to how to address.

like image 637
Techmag Avatar asked Dec 06 '25 05:12

Techmag


1 Answers

I'm guessing that you are using Crypto.encryptAES as a static method from outside of Play. That uses a global instance, which needs a running application because it uses applicationCache(). (Incidentally, this is why Play is removing static methods and global state whereever possible, because it is possible to get into states like this where a method is called with no application.)

In any case, Crypto is a wrapper around three other classes. What you want to do is instantiate a AESCTRCrypter, which has encryptAES.

https://github.com/playframework/playframework/blob/2.5.3/framework/src/play/src/main/scala/play/api/libs/crypto/Crypto.scala#L350

This uses a CryptoConfig, which you'll get from CryptoConfigParser:

https://github.com/playframework/playframework/blob/2.5.3/framework/src/play/src/main/scala/play/api/libs/crypto/Crypto.scala#L463

which will take an Environment and a Configuration -- these have lots of docs and factory methods on them so I won't go into details there.

Once you've done that, you can create your own wrapper class with a static method.

However, AESCTRCrypter is also deprecated, because this is not a secure use of symmetric encryption. Because it is deprecated and insecure, it will go away in a future version of Play, and then those compilation errors will be permanent and you will have to write your own replacement symmetric encryption code if you want to maintain AES-CTR without modification.

The recommended libraries are listed in the migration guide, and there's an example project at https://github.com/playframework/play-kalium.

In addition, there is an AES library called JNCryptor that is available on Maven, recommended by CossackLabs: https://cossacklabs.com/choose-android-crypto.html

https://github.com/RNCryptor/JNCryptor

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

EDIT: As of 2018, I recommend you use Google Tink.

like image 70
Will Sargent Avatar answered Dec 08 '25 12:12

Will Sargent



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!