Невозможно обменять AES-256-CBC / PKCS7 между C # bouncycastle и PHP openssl

поэтому у меня есть следующий код на C # и PHP, и пока результаты не согласуются между обеими сторонами. Для C # я использую API Bouncy Castle, а для PHP я использую openSSL. Просто чтобы быть уверенным, я также зашифровал то же самое в C # с помощью Microsoft Crypto Library, и я получил тот же текст шифра, но не тогда, когда они обмениваются с PHP.

C #

    public const string AES_ALGORITHM = "AES/CBC/PKCS7";
public const string CRYPTO_ALGORITHM = "AES";
public AESController(string key) {
encryptionKey = Convert.FromBase64String(key);
}
public string encrypt(string plainText, byte[] iv) {
string cipherText = "";
//setting up AES Key
KeyParameter aesKeyParam = ParameterUtilities.CreateKeyParameter(CRYPTO_ALGORITHM, encryptionKey);

// Setting up the Initialization Vector. IV is used for encrypting the first block of input message
ParametersWithIV aesIVKeyParam = new ParametersWithIV(aesKeyParam, iv);

// Create the cipher object for AES algorithm using GCM mode and NO padding
IBufferedCipher cipher = CipherUtilities.GetCipher(AES_ALGORITHM);
cipher.Init(true, aesIVKeyParam);

byte[] output = cipher.DoFinal(Encoding.UTF8.GetBytes(plainText));

cipherText = Convert.ToBase64String(output);
return cipherText;
}

public string decrypt(string cipherText, byte[] iv) {
string plainText = "";
//setting up AES Key
KeyParameter aesKeyParam = ParameterUtilities.CreateKeyParameter(CRYPTO_ALGORITHM, encryptionKey);

// Setting up the Initialization Vector. IV is used for encrypting the first block of input message
ParametersWithIV aesIVKeyParam = new ParametersWithIV(aesKeyParam, iv);

// Create the cipher object for AES algorithm using GCM mode and NO padding
IBufferedCipher cipher = CipherUtilities.GetCipher(AES_ALGORITHM);
cipher.Init(false, aesIVKeyParam);byte[] output = cipher.DoFinal(Convert.FromBase64String(cipherText));

plainText = Encoding.UTF8.GetString(output);
return plainText;
}

static void Main(string[] args) {
AESController aes = new AESController("OXzN4fxHHgcKtAt/SJ4UWtNiQlzno7II1gIBs24CWpY=");
byte[] iv = Base64.Decode("fdL8sKmhC8YIrYHMzoJJvQ==");
string encryptedText = "TESTING123";

string cipherText = aes.encrypt(encryptedText, iv);
Console.Out.WriteLine("IV: " + Encoding.UTF8.GetString(Base64.Encode(iv)));
Console.Out.WriteLine("Plain Text:"+aes.decrypt(cipherText, iv));
Console.Out.WriteLine("Cipher Text:" + cipherText);

Console.In.ReadLine();
}

а затем PHP:

    $key = "OXzN4fxHHgcKtAt/SJ4UWtNiQlzno7II1gIBs24CWpY=";
$iv = base64_decode("fdL8sKmhC8YIrYHMzoJJvQ==");
//$iv = openssl_random_pseudo_bytes(16);
//$cipherText = "YMdJ0mdWZ+p50krLzhyI0Q==";
$plainText = "TESTING123";
$decrypted = openssl_encrypt($plainText, "aes-256-cbc", $key, 0, $iv);

var_dump($decrypted);

Итак, зашифрованный текст из C # bouncycastle:

EnOtpv4fOGiAKMzXXJMYBA ==

и зашифрованный текст, который приходит из PHP:

Сз + F7A / DBEGma7iQ / PQVLw ==

и если я возьму этот текст c # шифра в PHP, расшифрованный результат будет: bool (False)
(шифрование не удалось)

Наконец, если в PHP я изменяю заполнение на OPENSSL_ZERO_PADDING и дешифрую зашифрованный текст из C #, результат будет следующим:

_XGmNSlZx

Насколько я могу понять, ключ и IV одинаковы для обоих (оба являются строкой BASE64), зашифрованные результаты имеют одинаковую длину (что объясняет два == в конце текста шифра. Есть что-то, что я пропускаю Или мне нужно сделать что-то особенное для библиотеки openssl? Спасибо.

1

Решение

В отличие от инструментов командной строки OpenSSL, PHP-функции openssl ожидают необработанные входные данные, а не закодированные в Base64.

В вашем PHP-коде вы не расшифровали Base64 ключ.

1

Другие решения

Других решений пока нет …