我正在尝试将C#中的加密转换为PHP

时间:2019-04-26 09:05:55

标签: c# php

我是php的新手,目前正在尝试将C#代码转换为php,

这是我尝试过的PHP代码

function cryptECB($crypt, $key) {
       //$iv_size = mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ECB);
         //$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        // crypting  
        $byteskey = "";
        for($i = 0; $i < mb_strlen($key, 'ASCII'); $i++)
        {
           $byteskey .= ord($key[$i]);
        }

        $buffer = "";
        for($i = 0; $i < mb_strlen($crypt, 'ASCII'); $i++)
        {
           $buffer .= ord($crypt[$i]);
        }

        $cryptText = mcrypt_encrypt(MCRYPT_3DES, $byteskey, $buffer, MCRYPT_MODE_ECB);
        return BytesToStr($cryptText);
}

function BytesToStr($data)
    {
        $value = "";
        for ($i = 0; $i < strlen($data); $i++)
        {
            $value .= (String)$data[i];
        }
        return $value;
    }

这里是我要转换的C#

public string DES3Encrypt(string data, string key)
        {
            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Mode = CipherMode.ECB;
            ICryptoTransform DESEncrypt = DES.CreateEncryptor();
            byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(data);
            return BytesToStr(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
            //return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
        }

public string BytesToStr(byte[] b)
        {
            string value = "";
            for (int i = 0; i < b.Length; i++)
            {
                value += b[i].ToString("X2");
            }
            return value;
        }

我希望得到相同的结果,但事实并非如此。如何在php中正确执行?

1 个答案:

答案 0 :(得分:0)

  • mcrypt_encrypt已过时。更好地使用openssl_encrypt。另一个优点:C#代码中的openssl_encryptTripleDESCryptoServiceProvider默认情况下都使用PKCS7-paddingmcrypt_encrypt使用零字节填充)。
  • PHP中的内置bin2hex对应于C#代码中的BytesToStr
  • openssl_encrypt期望键和数据为字符串。
  • 因此,代码很简单:

    function cryptECB($plaintext, $key) {
        //$ciphertext = openssl_encrypt($plaintext, 'DES-EDE', $key,  OPENSSL_RAW_DATA);  // 16-byte key
        $ciphertext = openssl_encrypt($plaintext, 'DES-EDE3', $key,  OPENSSL_RAW_DATA);   // 24-byte key
        return bin2hex($ciphertext);
    }
    
  • 注1:Triple-DES可以与其他键选项一起使用。 C#代码支持密钥大小16字节和24字节,其中密钥大小隐式确定相应的密钥选项。 相反,在PHP代码中,指定的密码方法确定了密钥选项,即,对于16字节密钥,必须使用DES-EDE密码方法,对于24字节密钥DES-EDE3密码方法。如果DES-EDE3用于16字节密钥,则通过附加0值将密钥扩展为24字节密钥。反之亦然,如果DES-EDE用于24字节密钥,则通过截断右侧将密钥缩短为16字节密钥。两者都将导致除C#代码以外的结果!
  • 注2:如果可能,不应使用ECB,因为它是insecure。另外,应使用AES代替Triple-DES,请参阅here