Php AES ECB encryption java decryption not working - java

I am writing an android application which connects to php web service. Actually there is a similar ios application working well, I am cloning it.
Between php and ios they use AES encryption/decryption. It works well. But with java encryption is ok but decryption is not working.Java encrypts and php understands but when php makes the encryption my java code is not good enough. I am writing below codes.
can anyone guide me, help me ?
PHP encryption :
echo base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
$key,
outputstring,
MCRYPT_MODE_ECB,
nil));
IOS decryption :
ccStatus = CCCrypt( encryptOrDecrypt,
kCCAlgorithmAES128,
kCCOptionECBMode,
(const void *)[symmetricKey bytes],
kCCKeySizeAES256,
nil,
(const void *) [plainText bytes],
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes
);
Java Decryption -NOT WORKING WELL- Not working means, using same data, same encryption, same key i can not get same output.
SecretKeySpec skey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance(AES/ECB/NoPadding, "BC");
cipher.init(Cipher.DECRYPT_MODE, skey);
result = decrypt(cipher, input);
I am looking an ideal solution for java decryption ? All helps are welcome ?

Related

Openssl encryption [Kotlin] [Android] (PHP)

Using api I have to connect to PHP project with encrypted login and password in Kotlin.
I need to use the same secret password as I use in PHP, but have problem with generating Secret Key by following line:
val sk = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8),"AES_256") //here exception is throwing
val iv = IvParameterSpec(secretKey.substring(0, 16).toByteArray(Charsets.UTF_8))
c.init(opmode, sk, iv)
That's my secret key:
ksjdg*&%$dfgh"{##!vcfkslc,.a/dcfxcsw345,45654gfdsgtrasd;fsdjf]}{O0-xfvbgdfeh=
The problem is that exception is throwing about unsupported key size. I got it.
But why using PHP and doing the same, using the same key, don't have any errors? :
$encryptionKey = `ksjdg*&%$dfgh"{##!vcfkslc,.a/dcfxcsw345,45654gfdsgtrasd;fsdjf]}{O0-xfvbgdfeh=`
$encrypted = openssl_encrypt($value, $encryptionMethod, $encryptionKey, 0, $iv);
What should do in Kotlin with my key to have it worked?

Java or Spring: two-way encryption with salt?

I am doing a web project with Spring.
I am hoping to do a two-way encryption (and decryption) of a few url parameters. I don't need very strong encryption.
I googled but found many are related to one-way password encryption, which is not what wanted.
Can any expert out there point me to the right place?
Thanks!
I can recommend really nice library called bouncy castle. On their homepage is a few nice examples. See https://www.bouncycastle.org/java.html
Another possibility is java crypto api and something like
SecretKey keySpec = new SecretKeySpec(keyBytes, "AES");
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher aesCbc = Cipher.getInstance("AES/CBC/NoPadding");
aesCbc.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encryptedBytes = aesCbc.doFinal(plainTextBytes);
return Base64.encodeBase64String(encryptedBytes);
You can you use classes from javax.crypto to perform encryption and decryption.

Configure Jasypt Encryptors using my own SecretKey, instead of setting String password using the 'setPassword' method of the PBEString encryptors?

I'm trying to configure Jasypt StandardPBEStringEncryptor using the following code.
StandardPBEStringEncryptor strongEncryptor = new StandardPBEStringEncryptor();
strongEncryptor.setAlgorithm(ALGORITHM);
strongEncryptor.setPassword(PASSWORD);
And then call the encrypt() and decrypt() methods of the 'strongEncryptor' to perform the encryption and decryption operations.
Is it possible or is there a way I can configure the Jasypt encryptor using my own SecretKey instead of setting a password?
Like in Java Cipher, we do...
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, MY_SECRET_KEY);
I see that Jasypt internally uses the String password to create the SecretKey and initiate the Java Cipher. Is it possible to provide my Key here?
PBE stands for Password Based Encryption.
That means instead of requiring a SecretKey it needs a passphrase which will then be used to generate the key by hashing it many times.
So manually settings the SecretKey for a PBE-encryption would invalidate it's purpose. For exactly that reason StandardPBEStringEncryptor does not allow this. (see it's doc for more information)
If you want to use your own SecretKey, simply use a standard encryption function.

Detecting incorrect key using AES/GCM in JAVA

I'm using AES to encrypt/decrypt some files in GCM mode using BouncyCastle.
While I'm proving wrong key for decryption there is no exception.
How should I check that the key is incorrect?
my code is this:
SecretKeySpec incorrectKey = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
byte[] block = new byte[1048576];
int i;
cipher.init(Cipher.DECRYPT_MODE, incorrectKey, ivSpec);
BufferedInputStream fis=new BufferedInputStream(new ProgressMonitorInputStream(null,"Decrypting ...",new FileInputStream("file.enc")));
BufferedOutputStream ro=new BufferedOutputStream(new FileOutputStream("file_org"));
CipherOutputStream dcOut = new CipherOutputStream(ro, cipher);
while ((i = fis.read(block)) != -1) {
dcOut.write(block, 0, i);
}
dcOut.close();
fis.close();
thanks
There is no method that you can detect incorrect key in GCM mode. What you can check is if the authentication tag validates, which means you were using the right key. The problem is that if the authentication tag is incorrect then this could indicate each of the following (or a combination of all, up to and including the full replacement of the ciphertext and authentication tag):
an incorrect key is being used;
the counter mode encrypted data was altered during transport;
the additional authenticated data was altered;
the authentication tag itself was altered during transport.
What you could do is send additional data to identify the secret key used. This could be a readable identifier ("encryption-key-1") but it could also be a KCV, a key check value. A KCV normally consists of a zero-block encrypted with the key, or a cryptographically secure hash over the key (also called a fingerprint). Because the encryption over a zero block leaks information you should not use that to identify the encryption key.
You could actually use the AAD feature of GCM mode to calculate the authentication tag over the key identification data. Note that you cannot distinguish between compromise of the fingerprint and using an incorrect key. It's however less likely that the fingerprint is accidentally damaged than the entire structure of IV, AAD, ciphertext and authentication tag.
You are using NoPadding. Change this to PKCS7Padding for both encryption and decryption. If the wrong key is used then the padding will almost certainly fail to decrypt as expected and an InvalidCipherTextException will be thrown.

What is the proper way to perform authenticated encryption in Java?

Authenticated encryption requires that we use some accepted standard for encrypting and authenticating a message. So we both encrypt the message and compute a MAC on the message to verify it has not been tampered with.
This question outlines a way to perform password based key strengthening and encryption:
/* Derive the key, given password and salt. */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
/* Encrypt the message. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));
But as far as I can tell, this does not compute any MAC on the ciphertext and so would be insecure. What is the accepted standard for performing authenticated encryption in Java?
I would recommend using GCM mode encryption. It is included in the latest JDK (1.7) by default. It uses a counter mode encryption (a stream cipher, no padding required) and adds an authentication tag. One big advantage is that it requires only a single key, whereas HMAC adds another key to the mix. Bouncy Castle has an implementation as well, which is moslty compatible with one provided by Oracle.
GCM mode encryption is also features in a TLS RFC, and in XML encrypt 1.1 (both not final). GCM mode provides all three security features: confidentiality, integrity and authenticity of the data send. The String would be "AES/GCM/NoPadding" instead of the CBC one you are now deploying. As said, make sure you have the latest JDK from Oracle, or have Bouncy Castle provider installed.
Also check out my answer here, which is mostly about String encoding, but I've succesfully tried GCM mode too - see the comment.
When transferring files from one server to another through secure ftp, I use private/public key pairs with the private key residing on the "from" server and the public key residing on the "to" server.
Using private/public key pairs is a secure standard when transferring files.
I believe it would also be a secure means in the context of a Java application.
Check out Generating and Verifying Signatures and Generate Public and Private Keys
for more details on using a private/public key pair setup for digital signatures in Java.

Categories