3DES шифрование с C # на PHP - PullRequest
1 голос
/ 06 июня 2019

Мне нужно шифрование php 3DES для создания метки времени для подключения к веб-сервису

Я хочу создать метку времени в php, у меня есть пример кода C #.Но мой php-код генерируется иначе, чем исходный код.

Вот мой php-код

class trytry{


    public function encrypt2($data, $secret)
    {
        //Generate a key from a hash
        $key = md5(utf8_encode($secret), true);

        //Take first 8 bytes of $key and append them to the end of $key.
        $key .= substr($key, 0, 8);

        //Pad for PKCS7
        $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
        $len = strlen($data);
        $pad = $blockSize - ($len % $blockSize);
        $data .= str_repeat(chr($pad), $pad);

        //Encrypt data
        $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');

        return base64_encode($encData);
    }

    public function decrypt2($data, $secret)
    {
        //Generate a key from a hash
        $key = md5(utf8_encode($secret), true);

        //Take first 8 bytes of $key and append them to the end of $key.
        $key .= substr($key, 0, 8);

        $data = base64_decode($data);

        $data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');

        $block = mcrypt_get_block_size('tripledes', 'ecb');
        $len = strlen($data);
        $pad = ord($data[$len-1]);

        return substr($data, 0, strlen($data) - $pad);
    }

    public function return_timestap(){

        date_default_timezone_set('GMT');
        return $date = date('D, d M Y H:i:s')." GMT" ;

        //." GMT" 
       // this is code to generate 
    }

}

Пример кода C #

using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;

namespace MemberSite.OddsDisplay.Helpers
{
    public class DES3
    {
        private byte[] bKey;
        private byte[] bIV;
        private SymmetricAlgorithm mCSP = new AesCryptoServiceProvider();

        public DES3(byte[] key)
        {
            bKey = key;
        }
        public DES3(byte[] key, byte[] iv)
        {
            bKey = key;
            bIV = iv;
        }
    }

    public string EncryptString(string Value)
        {
            ICryptoTransform ct;
            MemoryStream ms;
            CryptoStream cs;
            byte[] byt;
            mCSP.Key = bKey;
            mCSP.IV = bIV;
            mCSP.Mode = System.Security.Cryptography.CipherMode.ECB;
            mCSP.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
            ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV);
            byt = Encoding.UTF8.GetBytes(Value);
            ms = new MemoryStream();
            cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            return Convert.ToBase64String(ms.ToArray());
        }

    public string DecryptString(string Value)
        {
            ICryptoTransform ct;
            MemoryStream ms;
            CryptoStream cs;
            byte[] byt;
            mCSP.Key = bKey;
            mCSP.IV = bIV;
            mCSP.Mode = System.Security.Cryptography.CipherMode.ECB;
            mCSP.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
            ct = mCSP.CreateDecryptor(mCSP.Key, mCSP.IV);
            byt = Convert.FromBase64String(Value);
            ms = new MemoryStream();
            cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            return Encoding.UTF8.GetString(ms.ToArray());
        }

    public class Hash
    {
        public static string StringMD5(string data)
        {
            return (
                System.BitConverter.ToString(
                    System.Security.Cryptography.MD5.Create().ComputeHash(
                        System.Text.Encoding.UTF8.GetBytes(data)
                    )
                )
            );
        }
        public static byte[] BytesMD5(string data)
        {
            return (
                System.Security.Cryptography.MD5.Create().ComputeHash(
                    System.Text.Encoding.UTF8.GetBytes(data)
                )
            );
        }
    }
}



public string GetTimeStamp(string accessKey, string ivKey)
    {
        string timeStamp = string.Empty;

        byte[] key = Hash.BytesMD5(accessKey);
        byte[] ivbyte = Hash.BytesMD5(ivKey);
        DES3 des3 = new DES3(key, ivbyte);
        timeStamp = des3.EncryptString(getTimestampString(DateTime.Now));

        return timeStamp;
    }

Данные метки времени: чт, 06 июня2019 09:38:03 по Гринвичу

Результат PHP

QMaMk7ipbL73QLy6tbGBBG6vWJPBqsTEUt2mIpjKhjc =

Результат C #

0 0 0 0 0 0 0 0 0 0 0 6 0 0 6 0 0 6 0 uB-10

Может кто-нибудь объяснить и указать, почему мой код не работает?

Любая помощь будет высоко оценена

Заранее спасибо

1 Ответ

0 голосов
/ 06 июня 2019

Во-первых, ваш PHP использует тройки, но C # использует AES

Во-вторых, ключ в вашем коде C # и PHP не равны

В php у вас есть

    //Generate a key from a hash
    $key = md5(utf8_encode($secret), true);

    //Take first 8 bytes of $key and append them to the end of $key.
    $key .= substr($key, 0, 8);

Вы добавляете 8 байтов к ключу, чтобы он становился длиной ключа в 24 байта

Но в C #

    byte[] key = Hash.BytesMD5(accessKey);

Это длина ключа в 16 байтов.

Поскольку ваше требование заключается в том, чтобы PHP шифровался и дешифровался так же, как C #, поэтому я сконцентрировался на изменении только вашего php-кода

    public function encrypt2($data, $secret)
    {
        //Generate a key from a hash
        $key = md5(utf8_encode($secret), true);

        // Remove this
        //Take first 8 bytes of $key and append them to the end of $key.
        //$key .= substr($key, 0, 8);

        //Pad for PKCS7
        $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
        $len = strlen($data);
        $pad = $blockSize - ($len % $blockSize);
        $data .= str_repeat(chr($pad), $pad);

        //Encrypt data MCRYPT_RIJNDAEL_128, ECB equal to C# AES
        $encData = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB);

        return base64_encode($encData);
    }

    function decrypt2($data, $secret)
    {
        //Generate a key from a hash
        $key = md5(utf8_encode($secret), true);

        // Remove this
        //Take first 8 bytes of $key and append them to the end of $key.
        //$key .= substr($key, 0, 8);

        $data = base64_decode($data);

        $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB);

        $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
        $len = strlen($data);
        $pad = ord($data[$len-1]);

        return substr($data, 0, strlen($data) - $pad);
    }
...