String encryption PHP/Java - java

So, for a specific project I need to be able to encrypt and decrypt Strings in the same way that are encrypted/decrypted in another PHP application. My application is a Grails app, so I will be writing code in Java. The way the Strings will be encrypted/decrypted on the PHP side is (example code, not necessarily functional):
<?
$input="textToBeEncrypted";
function encrypt($data, $key)
{
$cipher_alg = MCRYPT_DES;
$mode = MCRYPT_MODE_CBC;
return #mcrypt_encrypt($cipher_alg, $key, $data, $mode);
}
function decrypt($encrypted, $key)
{
$cipher_alg = MCRYPT_DES;
$mode = MCRYPT_MODE_CBC;
return #mcrypt_decrypt($cipher_alg, $key, $encrypted, $mode);
}
$key ="testKey";
$data=$input;
$result = decrypt($data, $key);
echo ">>" . $result . "<br>\n";
?>
So, I would like to be able to apply the same encryption/decryption in Java (or Groovy). I have found this example code, https://github.com/stevenholder/PHP-Java-AES-Encrypt/blob/master/security.java and I understand that if I manage to find the names of the algorithm and mode in Java, it should work. Unless if I am missing something... I navigated to the Java Standard Names page for encrypting algorithms, http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html, but I can't find the exact equivalent of what I have in the PHP code. Any ideas? Has any of you guys ever needed to do something similar?
Thanks,
Iraklis

The three main things to consider with encryption are the algorithm, the mode, and the padding. Those must be compatible between the encryption and decryption software for everything to work.
To start with, AES (Rijndael) is definitely recommended in favor of DES as the encryption algorithm. DES is not considered secure enough any longer. The Java code you posted a link to is using AES, so it definitely won't be compatible with the PHP code you are showing.
Plus, that Java code is using ECB for the mode which is also not recommended. ECB is easier since it doesn't require any handling of initialization vectors but that is also its downfall. The PHP code is using CBC which is recommended, although I don't see any explicit IV handling. Mcrypt will use an IV of all zeros in that instance, which isn't ideal at all.
Finally the Java code is using PKCS5 as the padding method, whereas the PHP code uses zero-padding. Those aren't compatible. The default provider that comes with Oracle's JDK doesn't support zero padding, however Bouncy Castle does (see section 5.0). That would require either using Bouncy Castle's API directly or using it as a JCE provider using one of the methods detailed at that link. The the string "DES/CBC/ZeroByte" should do the trick.
Of course, zero padding can be problematic if the data you are encrypting can end with a null byte.
I've answered a question similar to this question before here and provided code for encrypting in Java and decrypting in PHP in the answer. Hopefully that might help you.

Related

trying to decrypt via php a password that i encrypted with javav

so my java looks like
String epassword = Crypt.encryptStringToString((String) params.get("password"));
I then store that in a DB. I need to decrypt it with PHP.
Is there a way to do this?
Thanks
I assume you are using uk.org.ellery.twiki.Crypt, since that's the only thing that came up when I search on Google for "encryptStringToString java".
In PHP, you will need to re-implement the class linked here:
http://svn.foswiki.org/trunk/EncryptedPagesPlugin/uk/org/ellery/twiki/Crypt.java
You're specifically interested in the "decryptString" method.
If it helps, looks like it generates a random salt which is stored with the encrypted value in the first 8 bytes, and the algorithm to apply the actual encryption/decryption is "PBEWithMD5AndDES", as provided by the standard Java crypto libraries. However, there's some wrapper code to convert values into hex values and a Base64 string (and vice versa).
Looks like someone has already ported PBEWithMD5AndDES to PHP, so you just need to re-write the Crypt.java file in PHP.

Java equivalent of C++ encryption [duplicate]

This question already has answers here:
How to decrypt file in Java encrypted with openssl command using AES?
(4 answers)
Closed 6 years ago.
I have this following snippet from c++ code that is used for encryption:
EVP_CIPHER_CTX ctx;
const EVP_CIPHER * cipher = EVP_des_ede3_cbc();
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char key[EVP_MAX_KEY_LENGTH];
String seed;
_config->get_value("crypto_seed", &seed); // uses the seed value from pimp config.
if (seed.is_empty())
{
return false;
}
EVP_BytesToKey(cipher, EVP_sha1(),
(unsigned char *) 0, // no salt
reinterpret_cast<unsigned char *>(const_cast<char *>(seed.chars())), seed.length(),
1, // hash passphrase just once.
key, iv);
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, cipher, (ENGINE *) 0, key,
iv,
1); // encrypt
what s the equivalent of the c++ encryption in java?
I see there is des algorithm, then i see sha1.
This is related to openssl encryption. But not sure what is the equivalent. essentially i would like the same output as c++ code generates.
i m asking the what s the equivalent of EVP_CIPHER_CTX or what s the name of the encrytion being used here so i can take it from there.
EDIT: not asking anyone to convert the code to java, just asking the corresponding package or class that would do the same.
The trickiest part of this is the EVP_BytesToKey part, which has been recreated before.
How to decrypt file in Java encrypted with openssl command using AES?
I've also got an object oriented version laying around here, if you are really not up to using that C-like code. For SHA-1, use SHA-1 instead of MD5...
As for the encryption, simply use "DESede/CBC/PKCS5Padding" as algorithm name for your Cipher.getInstance() method and you should be fine.
The code you are converting from uses the openssl library. It carries out a triple-DES encryption using an Initial Vector. The first thing you need to understand is exactly what it's doing (and preferably why).
Unfortunately the openssl documentation isn't terribly thorough (see here) ... though the O'Reilley book Network Security with OpenSSL is quite a bit better (it's a bit out of date, though).
Once you know what needs to be done, you shouldn't have much difficulty coding it in Java using the standard javax.crypto package.
The encryption being used is Triple DES with cipher block chaining
RSA page: source
A cryptographic identifier which indicates a 3DES EDE CBC symmetric
cipher.
It looks like EVP_CIPHER_CTX is the “context” structure that's containing the encryption (akin to an object), but the actual cypher being used is EVP_des_ede3_cbc — which would be "des-ede3-cbc" with OpenSSL.encrypt(…) and friends
EDIT: To answer the question (“the corresponding package”), generally you should probably use javax.crypto or (probably “better” for most purposes) bouncycastle (http://www.bouncycastle.org/). But OpenSSL bindings do also exist — just awkward to use and deploy.

Bouncycastle PBEWITHSHA256AND256BITAES-CBC-BC Javascript implementation

I've tried but failed to encode a string in Javascript to decode on a java server. We'd like to use the bouncycastle algorithm PBEWITHSHA256AND256BITAES-CBC-BC to decode serverside.
I've tried using crypto.js to do the encoding using the following code:
var encrypted = Crypto.AES.encrypt("it was Professor Plum in the library with the candlestick",
key,
{ mode: new Crypto.mode.CBC });
var encryptedString = Crypto.util.bytesToHex(Crypto.charenc.Binary.stringToBytes(crypted));
However this doesn't decode correctly on the server, my guess is its something to do with the SHA256 but I can't work out what it would be digesting & can't find any documentation. Does anyone know how to perform the encryption in javascript?
You need to do everything the same at both ends. You need the same key. You need the same mode (CBC) you need the same padding (use PKCS7) and you need the same IV.
Check that the actual key you are using is the same at both ends by displaying the hex, after you have run the passphrase through SHA-256. Check the hex for the IVs as well. Don't use any defaults, but explicitly pick the mode and padding to use.
If you think that it is the PBE/SHA-256 that is going wrong then you might want to look at how your text passphrase is being turned into bytes. Again, check the hex at both sides before it is passed to SHA-256. Converting text to bytes is a common source of errors. You need to be very sure what stringToBytes() is doing and that whatever you are using on the Java side is doing exactly the same.

AES Interoperability between PHP, Java, Javascript

I'm developing a HTTP API that requires encryption. I have tried to use AES to get compatibility between Java, PHP and Javascript, but so far I have managed to get Java<->PHP and then Java<->Javascript, but not both PHP and Javascript at the same time.
Has anyone had any experience with achieving interoperability between these languages and more?
Any advice would be much appreciated.
Thanks
To get AES to work across different systems, you have to make sure that everything is the same on all systems. That means not relying on system defaults for anything - defaults can differ between systems. You need to explicitly specify everything.
specify the mode; use CBC or CTR.
specify the IV. You can prepend it to the cyphertext.
specify the padding; for AES use PKCS7.
if your key is a text string then specify the character encoding used to convert it to bytes.
if your plaintext is a text string then specify the character encoding used to convert it to bytes.
AES is a standard (defined here). No matter which programming language you use, the result has to be the same.
Check some test vectors either from the official definition or - if you've already implemented a block mode of operation - from here.
If your implementation has different result, it might work, but it won't be AES...

Java to Python RSA

I'm trying to encrypt a string from Java to Python, using the library Bouncy Castle J2ME on the client side and Python M2Crypto on the other.
Everything is pretty good, I can decrypt it properly, but the padding is the issue.
The M2Crypto lib gives me (as far as I can tell) only these Padding schemes:
no_padding = 3
pkcs1_padding = 1
sslv23_padding = 2
pkcs1_oaep_padding = 4
While the bouncy castle J2ME only provides:
NoPadding
OAEPWithAndPadding
PKCS5Padding
SSL3Padding
So, I can use NoPadding between both, but then the strings that get generated after decryption are filled with jumbled characters.
I'd really like to get the padding sorted out, but I don't know how to convert between padding schemes / if that's even possible.
Please help me figure this out, it's killing me!
Bouncy castle provides padding. If you want for example to make an RSA with PKCS1 padding you have to do this:
public static PKCS1Encoding create_rsa_public(RSAKeyParameters PublicKey){
RSAEngine engine=new RSAEngine();
PKCS1Encoding encrypto=new PKCS1Encoding(engine);
encrypto.init(true,PublicKey);
return encrypto;
}
That function will return you an RSA engine with PKCS1Encoding.
I'm not familiar with Bouncy Castle but I guess you somehow use RSAEngine which implements AsymmetricBlockCipher thus you should be able to use PKCS1 or not?
And there also seems to be OAEP support, which given the right parameters should also work.

Categories