0

I am creating a JSON file in PHP and I need to transfer it to the kotlin app The requirements are that the information in the file be locked so that it cannot be modified

I used encryption and decryption in PHP and kotlin using SSL But I could not combine them

Where should I put PHP keys in kotlin?

These IS the codes I work with:

php

$cipher = "aes-128-ctr";
$iv = base64_decode("bVQzNFNhRkQ1Njc4UUFaWA==");
$plaintext = "Encryption information";
$ciphertext = openssl_encrypt($plaintext, $cipher, $kay, $options=0, $iv);
echo $ciphertext; // 19t56L06a5m934HbeJKoVDxGErTBgg==

Kotlin

    import android.util.Base64
    import javax.crypto.Cipher
    import javax.crypto.SecretKeyFactory
    import javax.crypto.spec.IvParameterSpec
    import javax.crypto.spec.PBEKeySpec
    import javax.crypto.spec.SecretKeySpec
    
    object AESEncyption {
        const val secretKey = "tK5UTui+DPh8lIlBxya5XVsmeDCoUl6vHhdIESMB6sQ="
        const val salt = "QWlGNHNhMTJTQWZ2bGhpV3U="
        const val iv = "bVQzNFNhRkQ1Njc4UUFaWA=="

        fun decrypt(strToDecrypt: String) : String? {
            try {
                val ivParameterSpec =  IvParameterSpec(Base64.decode(iv, Base64.DEFAULT))
                val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
                val spec =  PBEKeySpec(secretKey.toCharArray(), Base64.decode(salt, Base64.DEFAULT), 10000, 256)
                val tmp = factory.generateSecret(spec);
                val secretKey =  SecretKeySpec(tmp.encoded, "AES")
                val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
                cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
                return String(cipher.doFinal(Base64.decode(strToDecrypt, Base64.DEFAULT)))
            }
            catch (e: Exception) {
                println("Error while decrypting: $e");
            }
            return null
        }
    }

I deleted the unnecessary code

I do not know what is the secretKey and the salt in Kotlin code And where do I put the $cipher from PHP in the kotlin code

I switched to aes-128-gcm so I would not have to tag

mordi
  • 41
  • 1
  • 7
  • I cannot determine which is the "origin" source and what the "destination" source is. **When** Kotlin is the running code then you need to implement the key derivation function **PBKDF2** in PHP, using the same parameters as in Kotlin (salt, iterations, hash algorithm). Later you feed the PBKDF2 function with your passphrase, and you get the encryption key. – Michael Fehr Feb 15 '21 at 16:41
  • I don't know exactly what the details are in your case but if you just want to secure the transfer of data between client and server, no matter what the platforms/languages used in each, the correct answer is almost always to just use SSL/TLS. Writing your own ad-hoc low-level crypto code is hard to get right and hard to maintain. – President James K. Polk Feb 15 '21 at 17:17
  • Does this answer your question? [What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet?](https://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet) – BogdanBiv Feb 16 '21 at 10:54
  • @MichaelFehr I edited the question, I need to analyze `19t56L06a5m934HbeJKoVDxGErTBgg==` in Kotline code To "Encryption information". @PresidentJamesK.Polk @BogdanBiv I need to transfer the data in an external file not via SSL / TLS. – mordi Feb 16 '21 at 13:19

1 Answers1

0

There are several issues within your codes and my answer can just argue on how you present the encryption key (you called it "kay") to the encryption function.

As the encryption key looks like a Base64 encoded string the following steps base on that.

A) I'm decoding the key-string with this command:

$kay = base64_decode("tK5UTui+DPh8lIlBxya5XVsmeDCoUl6vHhdIESMB6sQ=");

and receive a key length of 32 bytes - that is important for the next step.

B) As your AES algorithm is set to AES-CTR-128 OpenSSL will strip of all bytes longer than 16 bytes. That said, how does your key looks like in hex encoding:

echo 'original key: ' . bin2hex(($kay)) . PHP_EOL;
original key:   b4ae544ee8be0cf87c948941c726b95d5b267830a8525eaf1e1748112301eac4
used key:       b4ae544ee8be0cf87c948941c726b95d
used key Base64 tK5UTui+DPh8lIlBxya5XQ==

C) you can test that yourself with both keys - both will result in the ciphertext (Base64 encoded) of

OM3XUymvpRm0bJdEVC+TiRc/VKy/lA==

and not, as you said in your question, 19t56L06a5m934HbeJKoVDxGErTBgg==.

D) now put all data together and switch to Kotlin (I'm using Java, but that should be no problem for you):

The simple program will return the original plaintext:

original plaintext: Encryption information

Security warning: The following code uses static secret keys and IV's, has no exception handling and is for educational purpose only:

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class SoAnswer {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        String ciphertextBase64 = "OM3XUymvpRm0bJdEVC+TiRc/VKy/lA==";
        byte[] ciphertext = Base64.getDecoder().decode(ciphertextBase64);
        byte[] key = Base64.getDecoder().decode("tK5UTui+DPh8lIlBxya5XQ==");
        byte[] iv = Base64.getDecoder().decode("bVQzNFNhRkQ1Njc4UUFaWA==");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] decryptedtext = cipher.doFinal(ciphertext);
        System.out.println("original plaintext: " + new String(decryptedtext));
    }
}
Michael Fehr
  • 5,827
  • 2
  • 19
  • 40