繁体   English   中英

将C#AES加密功能转换为PHP

[英]Converting C# AES encryption function to PHP

我正在尝试将C#加密函数转换为php,但我怀疑存在编码问题或IV代不正确。

这是用于将加密的文本发送到API的,并且我目前已尝试强制使用utf8,但base64编码的字符串始终不同于运行C#函数的字符串。 我似乎也找不到在C#中生成IV的确切方法。

可悲的是,我无法更改API解密的方式,因此我不得不以此方式对其进行加密。

C#功能

public void EncryptStringToBytes(string plaintext) {
            string key = DateTime.UtcNow.ToShortDateString();
            HashAlgorithm algorithm = SHA256.Create();
            byte[] bytekey = algorithm.ComputeHash(Encoding.UTF8.GetBytes(key));

            using (Aes myAes = Aes.Create()) {
                myAes.Key = bytekey;
                // Encrypt the string to an array of bytes.
                byte[] encrypted = null;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = myAes.CreateEncryptor(myAes.Key, myAes.IV);

                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream()) {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) {
                             //Write all data to the stream.
                             swEncrypt.Write(plaintext);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
                 Console.WriteLine(Convert.ToBase64String(encrypted)); 
                 Console.WriteLine(Convert.ToBase64String(myAes.IV));
            }
        }

PHP功能

date_default_timezone_set("UTC");

function encrypt($string) {
  // Generate key based on current time
  $secret_key = utf8_encode(date('Y-m-d'));
  // Hash the key with SHA256
  $key = hash('sha256', $secret_key);
  // Use AES 128 w/ CBC as encryption method
  $encrypt_method = "AES-128-CBC";
  // Get cipher length based on encryption method
  $cypher_length = openssl_cipher_iv_length($encrypt_method);
  // Generate IV -- possible issue
  $iv = openssl_random_pseudo_bytes($cypher_length);
  // Encrypt input string with the given method, key and IV
  $output = openssl_encrypt($string, $encrypt_method, $key, OPENSSL_RAW_DATA , $iv);

  $debug_info = [ 'date' => $secret_key, 'key' => $key, 'method' => $encrypt_method, 'cypher_len' => $cypher_length, 'iv' => $iv, 'output' => $output];
  return [base64_encode($output), base64_encode($iv), $debug_info];
}

由于bartonjs,我找到了解决方案,我不得不使用AES-256-CBC而不是128。此外,在散列时我也没有使用原始输出,这也改变了结果,因为我发送的是加密数据和IV槽php-使用SoapClient进行肥皂操作我不必使用base64_encode,因为SoapClient已经为我做到了。

工作代码如下:

    function encrypt($string, $debug = false) {
        $method = 'aes-256-cbc';
        $secret_key = date('Y-m-d', time());
        $key = hash('SHA256', $secret_key, true);
        $cypher_length = openssl_cipher_iv_length($method);
        $iv = random_bytes($cypher_length);
        $output = openssl_encrypt($string, $method, $key, OPENSSL_RAW_DATA, $iv);
        $debug_info = [ 'date' => $secret_key, 'date_utf8' => utf8_encode($secret_key), 'key' => utf8_encode($key), 'method' => $method, 'cypher_len' => $cypher_length, 'iv' => base64_encode($iv), 'output' => base64_encode($output)];

        if($debug){
            return [$output, $iv, $debug_info];
        }
        return [$output, $iv];
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM