将加密和解密 C# 函数转换为 PHP 函数

问题描述 投票:0回答:3

我想将 C# 函数转换为 PHP 函数。 这是 C# 中函数的链接:https://stackoverflow.com/a/19441805/3581428

public static string Encrypt(string clearText)
{
    string EncryptionKey = "MAKV2SPBNI99212";
    byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new 
            Rfc2898DeriveBytes(EncryptionKey, new byte[] 
            { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
                cs.Close();
            }
            clearText = Convert.ToBase64String(ms.ToArray());
        }
    }
    return clearText;
}

public static string Decrypt(string cipherText)
{
    string EncryptionKey = "MAKV2SPBNI99212";
    byte[] cipherBytes = Convert.FromBase64String(cipherText);
    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new 
            Rfc2898DeriveBytes(EncryptionKey, new byte[] 
            { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(cipherBytes, 0, cipherBytes.Length);
                cs.Close();
            }
            cipherText = Encoding.Unicode.GetString(ms.ToArray());
        }
    }
    return cipherText;
}

我在下面的函数中尝试过,但它创建了不同的加密字符串:

function encrypt_decrypt($action, $string) {
    $output = false;

$encrypt_method = "AES-256-CBC";
$secret_key = '3sc3RLrpd17';

$secret_iv=chr(0x49).chr(0x76).chr(0x61).chr(0x6e).chr(0x20).chr(0x4d).chr(0x65).chr(0x64).chr(0x76).chr(0x65).chr(0x64).chr(0x65).chr(0x76);


$key = substr(hash('sha1', $secret_key), 0, 32);;
//echo "key: ".$key."<br>";

$iv = substr(hash('sha1', $secret_iv), 0, 16);
//echo "iv key: ".$iv."<br>";
if( $action == 'encrypt' ) {
    $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
    $output = base64_encode($output);
}
else if( $action == 'decrypt' ){
    $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}

return $output;
}

$plain_txt = "1122334411223344";
echo "Plain Text = $plain_txt\n"."<br/>";

$encrypted_txt = encrypt_decrypt('encrypt', $plain_txt);
echo "Encrypted Text = $encrypted_txt\n"."<br/>";

$decrypted_txt = encrypt_decrypt('decrypt', $encrypted_txt);
echo "Decrypted Text = $decrypted_txt\n"."<br/>";

if( $plain_txt === $decrypted_txt ) echo "SUCCESS"."<br/>";
else echo "FAILED"."<br/>";

echo "\n"."<br/>";
exit;

使用 C# 方法加密字符串:

thkTvpUmSWV9lKAOfWNIIu9n7jHcku7C6WDD/hsvll+xjqOWdk3fyI+eRhBbvJlX

长度是64

使用 PHP 方法加密字符串:

OTlIYXJDcTl0SVpKRlhaV0l3dFk1ZjFYM3FPcHB3ckdTRERITGhHVEVoTT0=

长度是60

如何生成与 C# 函数相同的加密字符串?如何为 PHP 复制 C# 函数?

能够使用此示例链接创建长度为 64 位的加密文本:AES ENCRYPTION 64 位长度的加密字符串

c# php encryption php-openssl
3个回答
13
投票

请试试这个(测试版):

PHP

<?php

$plaintext = 'My secret message 1234';
$password = '3sc3RLrpd17';
$method = 'aes-256-cbc';

// Must be exact 32 chars (256 bit)
$password = substr(hash('sha256', $password, true), 0, 32);
echo "Password:" . $password . "\n";

// IV must be exact 16 chars (128 bit)
$iv = chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0);

// av3DYGLkwBsErphcyYp+imUW4QKs19hUnFyyYcXwURU=
$encrypted = base64_encode(openssl_encrypt($plaintext, $method, $password, OPENSSL_RAW_DATA, $iv));

// My secret message 1234
$decrypted = openssl_decrypt(base64_decode($encrypted), $method, $password, OPENSSL_RAW_DATA, $iv);

echo 'plaintext=' . $plaintext . "\n";
echo 'cipher=' . $method . "\n";
echo 'encrypted to: ' . $encrypted . "\n";
echo 'decrypted to: ' . $decrypted . "\n\n";

exit;

C#

    public string EncryptString(string plainText, byte[] key, byte[] iv)
    {
        // Instantiate a new Aes object to perform string symmetric encryption
        Aes encryptor = Aes.Create();

        encryptor.Mode = CipherMode.CBC;

        // Set key and IV
        byte[] aesKey = new byte[32];
        Array.Copy(key, 0, aesKey, 0, 32);
        encryptor.Key = aesKey;
        encryptor.IV = iv;

        // Instantiate a new MemoryStream object to contain the encrypted bytes
        MemoryStream memoryStream = new MemoryStream();

        // Instantiate a new encryptor from our Aes object
        ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();

        // Instantiate a new CryptoStream object to process the data and write it to the 
        // memory stream
        CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);

        // Convert the plainText string into a byte array
        byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);

        // Encrypt the input plaintext string
        cryptoStream.Write(plainBytes, 0, plainBytes.Length);

        // Complete the encryption process
        cryptoStream.FlushFinalBlock();

        // Convert the encrypted data from a MemoryStream to a byte array
        byte[] cipherBytes = memoryStream.ToArray();

        // Close both the MemoryStream and the CryptoStream
        memoryStream.Close();
        cryptoStream.Close();

        // Convert the encrypted byte array to a base64 encoded string
        string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);

        // Return the encrypted data as a string
        return cipherText;
    }

    public string DecryptString(string cipherText, byte[] key, byte[] iv)
    {
        // Instantiate a new Aes object to perform string symmetric encryption
        Aes encryptor = Aes.Create();

        encryptor.Mode = CipherMode.CBC;

        // Set key and IV
        byte[] aesKey = new byte[32];
        Array.Copy(key, 0, aesKey, 0, 32);
        encryptor.Key = aesKey;
        encryptor.IV = iv;

        // Instantiate a new MemoryStream object to contain the encrypted bytes
        MemoryStream memoryStream = new MemoryStream();

        // Instantiate a new encryptor from our Aes object
        ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();

        // Instantiate a new CryptoStream object to process the data and write it to the 
        // memory stream
        CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);

        // Will contain decrypted plaintext
        string plainText = String.Empty;

        try
        {
            // Convert the ciphertext string into a byte array
            byte[] cipherBytes = Convert.FromBase64String(cipherText);

            // Decrypt the input ciphertext string
            cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);

            // Complete the decryption process
            cryptoStream.FlushFinalBlock();

            // Convert the decrypted data from a MemoryStream to a byte array
            byte[] plainBytes = memoryStream.ToArray();

            // Convert the decrypted byte array to string
            plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
        }
        finally
        {
            // Close both the MemoryStream and the CryptoStream
            memoryStream.Close();
            cryptoStream.Close();
        }

        // Return the decrypted data as a string
        return plainText;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        string message = "My secret message 1234";
        string password = "3sc3RLrpd17";

        // Create sha256 hash
        SHA256 mySHA256 = SHA256Managed.Create();
        byte[] key = mySHA256.ComputeHash(Encoding.ASCII.GetBytes(password));

        // Create secret IV
        byte[] iv = new byte[16] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };

        string encrypted = this.EncryptString(message, key, iv);
        string decrypted = this.DecryptString(encrypted, key, iv);

        Console.WriteLine(encrypted);
        Console.WriteLine(decrypted);
    }

0
投票

正如@odan 给出的那样,对那些需要 PHP、openssl_encrypt 和 AES-128-CBC、密钥和 IV 的人进行了微小的更改,在 PHP 代码下方

$plaintext = 'My secret message 1234';
$key = '3d756227f8be6f85';
// CBC has an IV and thus needs randomness every time a message is encrypted
$method = 'AES-128-CBC';
$iv = 'ba7e0bb79b61f82d';

$cipher  =   openssl_encrypt($plaintext, $method, $key, $options=OPENSSL_RAW_DATA,$iv );
$body=       base64_encode($cipher);
echo $body;
$decrypted = openssl_decrypt($cipher, $method, $key, OPENSSL_RAW_DATA, $iv);
echo ' decrypted to: ' . $decrypted . "\n\n";

和小提琴中的 C# 代码链接:https://dotnetfiddle.net/LE8lTx

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

public class Program
{
    public static void Main()
    {
        string message = "My secret message 1234";
        string password = "3d756227f8be6f85";
        string ivstr = "ba7e0bb79b61f82d";  
        
        Program p=new Program();

        string encrypted = p.EncryptString(message, password, ivstr);
        string decrypted = p.DecryptString(encrypted, password, ivstr);
                

        Console.WriteLine(encrypted);
        Console.WriteLine(decrypted);
        
    }
    
    public  string EncryptString(string plainText, string password,string ivstr)
    {
         byte[] key = Encoding.UTF8.GetBytes(password);
         byte[] iv = Encoding.UTF8.GetBytes(ivstr);
        // Instantiate a new Aes object to perform string symmetric encryption
        Aes encryptor = Aes.Create();

        encryptor.Mode = CipherMode.CBC;

        // Set key and IV
        byte[] aesKey = new byte[16];
        Array.Copy(key, 0, aesKey, 0, 16);
        encryptor.Key = aesKey;
        encryptor.IV = iv;

        // Instantiate a new MemoryStream object to contain the encrypted bytes
        MemoryStream memoryStream = new MemoryStream();

        // Instantiate a new encryptor from our Aes object
        ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();

        // Instantiate a new CryptoStream object to process the data and write it to the 
        // memory stream
        CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);

        // Convert the plainText string into a byte array
        byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);

        // Encrypt the input plaintext string
        cryptoStream.Write(plainBytes, 0, plainBytes.Length);

        // Complete the encryption process
        cryptoStream.FlushFinalBlock();

        // Convert the encrypted data from a MemoryStream to a byte array
        byte[] cipherBytes = memoryStream.ToArray();

        // Close both the MemoryStream and the CryptoStream
        memoryStream.Close();
        cryptoStream.Close();

        // Convert the encrypted byte array to a base64 encoded string
        string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);

        // Return the encrypted data as a string
        return cipherText;
    }

    public  string DecryptString(string cipherText,  string password,string ivstr)
    {
         byte[] key = Encoding.UTF8.GetBytes(password);
         byte[] iv = Encoding.UTF8.GetBytes(ivstr);
        
        // Instantiate a new Aes object to perform string symmetric encryption
        Aes encryptor = Aes.Create();

        encryptor.Mode = CipherMode.CBC;

        // Set key and IV
        byte[] aesKey = new byte[16];
        Array.Copy(key, 0, aesKey, 0, 16);
        encryptor.Key = aesKey;
        encryptor.IV = iv;

        // Instantiate a new MemoryStream object to contain the encrypted bytes
        MemoryStream memoryStream = new MemoryStream();

        // Instantiate a new encryptor from our Aes object
        ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();

        // Instantiate a new CryptoStream object to process the data and write it to the 
        // memory stream
        CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);

        // Will contain decrypted plaintext
        string plainText = String.Empty;

        try
        {
            // Convert the ciphertext string into a byte array
            byte[] cipherBytes = Convert.FromBase64String(cipherText);

            // Decrypt the input ciphertext string
            cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);

            // Complete the decryption process
            cryptoStream.FlushFinalBlock();

            // Convert the decrypted data from a MemoryStream to a byte array
            byte[] plainBytes = memoryStream.ToArray();

            // Convert the decrypted byte array to string
            plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
        }
        finally
        {
            // Close both the MemoryStream and the CryptoStream
            memoryStream.Close();
            cryptoStream.Close();
        }

        // Return the decrypted data as a string
        return plainText;
    }
}

0
投票

我建议您使用我已经为此目的用 C# 和 PHP 编写的类似类:

我的

Cryptography
PHP 课程

class Cryptography{
    private $Method = 'aes-256-cbc';
    private $Password = null;
    private $Cost = 12;

    public function __construct($password = null, $cost = null){
        $this->Password = $password??"my default password";
        $this->Cost = $cost??12;
    }
    
    public function Encrypt($plaintext, $password = null, $cost = null){
        return base64_encode(
            openssl_encrypt(
                $plaintext, 
                $this->Method, 
                $this->GetKey($password, $cost),
                OPENSSL_RAW_DATA,
                $this->GetIV()
            )
        );
    }
    
    public function Decrypt($ciphertext, $password = null, $cost = null){
        return openssl_decrypt(
            base64_decode($ciphertext),
            $this->Method,
            $this->GetKey($password, $cost),
            OPENSSL_RAW_DATA,
            $this->GetIV()
        );
    }
    
    
    private function GetKey($password = null, $cost = null){
        return password_hash($password??$this->Password, PASSWORD_BCRYPT, ['cost' => $cost??$this->Cost]);
    }
    private function GetIV(){
        return chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0);
    }
}

这个是 C# 中的一个类似的类

class Cryptography
{
    private string Password = null;
    private int Cost = null;

    public Cryptography(string password = null, int? cost = null)
    {
        Password = password??"my default password";
        Cost = cost??12;
    }

    public string Encrypt(string plainText, string password = null, int? cost = null)
    {
        // Instantiate a new Aes object to perform string symmetric encryption
        Aes encryptor = Aes.Create();

        encryptor.Mode = CipherMode.CBC;
        //encryptor.KeySize = 256;
        //encryptor.BlockSize = 128;
        //encryptor.Padding = PaddingMode.Zeros;

        // Set key and IV
        encryptor.Key = GetKey(password,cost).Take(32).ToArray();
        encryptor.IV = GetIV();

        // Instantiate a new MemoryStream object to contain the encrypted bytes
        MemoryStream memoryStream = new MemoryStream();

        // Instantiate a new encryptor from our Aes object
        ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();

        // Instantiate a new CryptoStream object to process the data and write it to the 
        // memory stream
        CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);

        // Convert the plainText string into a byte array
        byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);

        // Encrypt the input plaintext string
        cryptoStream.Write(plainBytes, 0, plainBytes.Length);

        // Complete the encryption process
        cryptoStream.FlushFinalBlock();

        // Convert the encrypted data from a MemoryStream to a byte array
        byte[] cipherBytes = memoryStream.ToArray();

        // Close both the MemoryStream and the CryptoStream
        memoryStream.Close();
        cryptoStream.Close();

        // Convert the encrypted byte array to a base64 encoded string
        string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);

        // Return the encrypted data as a string
        return cipherText;
    }

    public string Decrypt(string cipherText, string password = null, int? cost = null)
    {
        // Instantiate a new Aes object to perform string symmetric encryption
        Aes encryptor = Aes.Create();

        encryptor.Mode = CipherMode.CBC;
        //encryptor.KeySize = 256;
        //encryptor.BlockSize = 128;
        //encryptor.Padding = PaddingMode.Zeros;

        // Set key and IV
        encryptor.Key = GetKey(password, cost).Take(32).ToArray();
        encryptor.IV = GetIV();

        // Instantiate a new MemoryStream object to contain the encrypted bytes
        MemoryStream memoryStream = new MemoryStream();

        // Instantiate a new encryptor from our Aes object
        ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();

        // Instantiate a new CryptoStream object to process the data and write it to the 
        // memory stream
        CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);

        // Will contain decrypted plaintext
        string plainText = String.Empty;

        try
        {
            // Convert the ciphertext string into a byte array
            byte[] cipherBytes = Convert.FromBase64String(cipherText);

            // Decrypt the input ciphertext string
            cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);

            // Complete the decryption process
            cryptoStream.FlushFinalBlock();

            // Convert the decrypted data from a MemoryStream to a byte array
            byte[] plainBytes = memoryStream.ToArray();

            // Convert the decrypted byte array to string
            plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
        }
        finally
        {
            // Close both the MemoryStream and the CryptoStream
            memoryStream.Close();
            cryptoStream.Close();
        }

        // Return the decrypted data as a string
        return plainText;
    }

    private byte[] GetKey(string password = null, int? cost = null)
    {
        // hash the password with BCrypt
        string hashedPassword = BCrypt.Net.BCrypt.HashPassword(password??Password, cost??Cost);

        // Convert hashed password to array
        return Encoding.ASCII.GetBytes(hashedPassword);
    }
    private byte[] GetIV()
    {
        // Create secret IV
        return new byte[16] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
    }

}

参考:https://gist.github.com/Oranzh/2520823f9d1cea603e60b8e8f3fe1d36

享受...

© www.soinside.com 2019 - 2024. All rights reserved.