Home > Software engineering >  Converting php array substr to c#
Converting php array substr to c#

Time:11-16

I'm trying to decrypt in c#, using bouncycastle, the result of the following php code:

<?php
    $plaintext = 'The quick brown fox jumps over the lazy dog';
    $cipher = "AES-128-CTR";
    $key = "F5UgsDQddWGdgjdd";
    $iv = openssl_random_pseudo_bytes(16);
    $ciphertext = openssl_encrypt(
        $plaintext, 
        $cipher,   
        $key,
        0, 
        $iv
    );
    $ciphertext = base64_encode($iv.$ciphertext);
    echo $ciphertext."\n";
?>

in php, the following code works:

<?php
    $cipher = "AES-128-CTR";
    $key = "F5UgsDQddWGdgjdd";    
    $ciphertext = base64_decode( $_POST['ciphertext'] );
    $iv = substr($ciphertext, 0, 16);
    $content = substr($ciphertext, 16);
    $text = openssl_decrypt(
        $content, 
        $cipher,
        $key,  
        0, 
        $iv
      );
    
    echo $text."\n";
?>

However, when I do the following in C# the result is just gibberish.

public string Test(string cipherTextStr)
{
    var cipherText = Convert.FromBase64String(cipherTextStr);
    var iv = cipherText.Take(16).ToArray();
    var content = cipherText.Skip(16).ToArray();

    byte[] keyBytes = Encoding.UTF8.GetBytes("F5UgsDQddWGdgjdd");

    IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");

    cipher.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", keyBytes), iv));

    byte[] decryptedBytes = cipher.DoFinal(content);

    return Encoding.UTF8.GetString(decryptedBytes);

}

The same C# code works if I don't have to separate iv and content which makes me think that I'm either doing the initial FromBase64String wrong or the take and skip from the byte array.

CodePudding user response:

When you pass $option = 0 to openssl_encrypt, the input data is PKCS#7 padded and the output data is base64 encoded. If you don't want any padding and base64 encoded output, use this option value:

$ciphertext = openssl_encrypt(
    $plaintext, 
    $cipher,   
    $key,
    OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, 
    $iv
);

Update: modify C#, manually decode the encrypted data.

content = Convert.FromBase64String(Encoding.UTF8.GetString(content));
  • Related