C# расшифровка данных из Yii2, в частности, сравнение MAC.

Итак, теперь у меня есть рабочая версия функции расшифровки AES, которая берет данные с сервера с yii2 в качестве фреймворка. Yii2 имеет встроенное шифрование по ключу и дешифрование по ключу. У меня есть yii2 для использования AES-192-CBC. Недавно я получил помощь, пытаясь выяснить, как расшифровать данные и выполнил эту задачу с помощью пользователя VSTM.

Если кто-то хочет увидеть первую проблему, посмотрите проблему здесь.

Итак, я уверен, что моя проблема где-то в том, как данные отправляются и принимаются. Я думаю, что мне нужно как-то преобразовать его, чтобы можно было правильно сравнить отправленный код аутентификации сообщений с данными и MAC-адрес, который я вычисляю.

Yii2 и написанная мной форма C# используют sha256 для хеширования данных. Код Yii2 ниже.

$helpers = new Json();
    $data = $helpers::encode($array);
    Yii::$app->security->cipher = "AES-192-CBC";

    $string = Yii::$app->security->encryptByKey($data, $key);

    $response = Yii::$app->getResponse();



    $response->format = yii\web\Response::FORMAT_RAW;
    $response->content = $string;
    return $response->send();

Этот блок кода возвращает зашифрованную строку в программу через веб-запрос в формате. [KeySalt][MAC][IV][шифротекста]

Я получаю эти данные в C# со следующим кодом.

try
        {

            var data = new MemoryStream();
            var WR = (HttpWebRequest)WebRequest.Create(url);
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.DefaultConnectionLimit = 9999;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
            WR.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
            WR.UserAgent = "MultiPoolMiner V" + Application.ProductVersion;
            var Response = WR.GetResponse();

            var SS = Response.GetResponseStream();
            SS.ReadTimeout = 20 * 100;
            SS.CopyTo(data);

            Response.Close();

            byte[] dataByteArray = data.ToArray();

            string plainTextData = Utils.AesCipher.DecryptString(dataByteArray, password);
            //check if ticks from the db is bigger than 0;

        }
        catch (Exception e)
        {

        }

ниже находится функция decryptString

public static string DecryptString(byte[] allBytes, string password)
    {

        byte[] one = new byte[] { 1 };
        string plaintext = null;
        // this is all of the bytes

        byte[] passwordByteArray = ToByteArray(password);

        using (var aes = Aes.Create())
        {
            aes.KeySize = KeySize;
            aes.BlockSize = BlockSize;
            aes.Mode = CipherMode.CBC;


            // get the key salt
            byte[] keySalt = new byte[KeySize / 8];
            Array.Copy(allBytes, keySalt, keySalt.Length);

            // Yii2 says 
            //$key = $this->hkdf($this->kdfHash, $secret, $keySalt, $info, $keySize);
            //
            //Yii2 hkdf says
            //$prKey = hash_hmac($algo, $inputKey, $salt, true);
            //$hmac = '';
            //$outputKey = '';
            //for ($i = 1; $i <= $blocks; $i++) {
            //  $hmac = hash_hmac($algo, $hmac . $info . chr($i), $prKey, true);
            //  $outputKey .= $hmac;
            //}
            // chr($i) is the char byte of 1; 
            // the blocksize is 1
            // info here is nothing

            // hash first key with keysalt and password
            HMACSHA256 hmac = new HMACSHA256(keySalt);
            byte[] computedHash = hmac.ComputeHash(passwordByteArray);

            // hash primary key with one byte and computed hash
            HMACSHA256 hmac2 = new HMACSHA256(computedHash);
            byte[] prKeyFull = hmac2.ComputeHash(one);
            byte[] key = new byte[KeySize / 8];
            Array.Copy(prKeyFull, 0, key, 0, key.Length);

            //create the 32 byte array of all 0's for hashing the MAC authKey
            byte[] zeroByte = ToByteArray("\0");
            byte[] newSalt = new byte[32];

            for (int i = 0; i < 32; i++)
            {
                newSalt[i] = zeroByte[0];
            }

            //calculate MAC authKey
            // Yii2 is again using the hkdf function as above. Except this time info is "AuthorizationKey".
            HMACSHA256 hmac3 = new HMACSHA256(newSalt);
            byte[] preAuthKey = hmac3.ComputeHash(key);


            string authKeyInfo = "AuthorizationKey";
            byte[] authkeyInfoByteArray = ToByteArray(authKeyInfo);
            // add text authorizationkey and the byte 1 together. 
            byte[] actualByteArrayInfo = new byte[authkeyInfoByteArray.Length + one.Length];
            Array.Copy(authkeyInfoByteArray, actualByteArrayInfo, authkeyInfoByteArray.Length);
            Array.Copy(one, 0, actualByteArrayInfo, authkeyInfoByteArray.Length, one.Length);

            //second hash of authKey
            HMACSHA256 hmac4 = new HMACSHA256(preAuthKey);
            byte[] authKeyFull = hmac4.ComputeHash(actualByteArrayInfo);
            byte[] authKey = new byte[24];
            Array.Copy(authKeyFull, authKey, authKey.Length);


            // get the MAC code
            byte[] MAC = new byte[MacHashSize / 8];
            Array.Copy(allBytes, keySalt.Length, MAC, 0, MAC.Length);

            // get our IV
            byte[] iv = new byte[BlockSize / 8];
            Array.Copy(allBytes, (keySalt.Length + MAC.Length), iv, 0, iv.Length);

            // get the data we need to decrypt
            byte[] cipherBytes = new byte[allBytes.Length - iv.Length - MAC.Length - keySalt.Length];
            Array.Copy(allBytes, (keySalt.Length + MAC.Length + iv.Length), cipherBytes, 0, cipherBytes.Length);


            // if we want to verify the mac hash this is where we would do it. 
            // Yii2 encryption data. 
            // $encrypted = openssl_encrypt($data, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
            //
            //$authKey = $this->hkdf($this->kdfHash, $key, null, $this->authKeyInfo, $keySize);
            //hashed = $this->hashData($iv . $encrypted, $authKey);
            //hashed = [macHash][data]

            //so I'm putting together the data to hash. 
            byte[] dataToHash = new byte[cipherBytes.Length + iv.Length];
            // fist is the iv
            Array.Copy(iv, dataToHash, iv.Length);
            // then the data. 
            Array.Copy(cipherBytes, 0, dataToHash, iv.Length, cipherBytes.Length);

            // hash data to get the MAC
            HMACSHA256 hmac5 = new HMACSHA256(dataToHash);
            byte[] calculatedMacHash = hmac5.ComputeHash(authKey);

            // the calculatedMacHash I come out with is not the same as the MAC that I copied from the 
            // string response. I have verified all of the keys up to the point of hashing the MAC. 


            // Create a decrytor to perform the stream transform.
            var decryptor = aes.CreateDecryptor(key, iv);

            // Create the streams used for decryption. 
            using (MemoryStream msDecrypt = new MemoryStream(cipherBytes))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                         //Read the decrypted bytes from the decrypting stream 
                         //and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                        plaintext = plaintext.Remove(0, 32);
                    }
                }
            }
        }

        return plaintext;
    }

    public static byte[] ToByteArray(string value)
    {
        byte[] allBytes = new byte[value.Length];
        int i = 0;
        foreach (byte bite in value)
        {
            allBytes[i] = Convert.ToByte(bite);
            i++;
        }

        return allBytes;
    }

Так что моя проблема в том, что когда я вычисляю хеш-код MAC из моих ключей, которые были проверены как правильные ключи для ключей в yii2, я получаю байтовый массив, отличный от байтового массива, который передается как MAC, Я думаю, у меня проблемы с тем, что MAC не является необработанными данными, такими как зашифрованный текст. В yii2 все ключи возвращаются как необработанные данные. За исключением MAC, которого нет.

пример хэша = [MAC][данные]

ace6008a19b91a8d684c2970d31ab6aa7ac4d928be589dddd54d88146a9a57dc;siQ v H o @ ^ 8 ����躒�%Ō6I� .4����>*�Q�I!��R�k���eØ* O�>+�M�g� 4Kk K ܇;N垑H P " K Ql t u tE&

0 ответов

Другие вопросы по тегам