PHP和C#AES256加密 - >解密

时间:2017-04-19 19:42:59

标签: c# php encryption aes php-openssl

我想在PHP中加密文本并在C#中解密,但我不能。

这是我的PHP代码:

define('AES_256_ECB', 'aes-256-ecb');
$encryption_key = "SomeSimpleTest";
$data = "Test123";
$encryptedData = openssl_encrypt($data, AES_256_ECB, $encryption_key, 0);

..这是我的C#代码:

(AESEncryption.cs班)

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

    namespace AESCrypto
    {
        class AESEncryption
        {
            public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
            {
                byte[] decryptedBytes = null;
                // Set your salt here to meet your flavor:
                byte[] saltBytes = passwordBytes;
                // Example:
                //saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 256;

                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);

                        AES.Mode = CipherMode.ECB;
                        //AES.Padding = PaddingMode.PKCS7;

                        using (CryptoStream cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                            cs.Close();
                        }
                        decryptedBytes = ms.ToArray();
                    }
                }

                return decryptedBytes;
            }

            public static string Decrypt(string decryptedText, byte[] passwordBytes)
            {
                byte[] bytesToBeDecrypted = Convert.FromBase64String(decryptedText);

                // Hash the password with SHA256
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

                byte[] decryptedBytes = AES_Decrypt(bytesToBeDecrypted, passwordBytes);

                // Getting the size of salt
                int saltSize = GetSaltSize(passwordBytes);

                // Removing salt bytes, retrieving original bytes
                byte[] originalBytes = new byte[decryptedBytes.Length - saltSize];
                for (int i = saltSize; i < decryptedBytes.Length; i++)
                {
                    originalBytes[i - saltSize] = decryptedBytes[i];
                }

                return Encoding.UTF8.GetString(originalBytes);
            }

            public static int GetSaltSize(byte[] passwordBytes)
            {
                var key = new Rfc2898DeriveBytes(passwordBytes, passwordBytes, 1000);
                byte[] ba = key.GetBytes(2);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < ba.Length; i++)
                {
                    sb.Append(Convert.ToInt32(ba[i]).ToString());
                }
                int saltSize = 0;
                string s = sb.ToString();
                foreach (char c in s)
                {
                    int intc = Convert.ToInt32(c.ToString());
                    saltSize = saltSize + intc;
                }

                return saltSize;
            }

            public static byte[] GetRandomBytes(int length)
            {
                byte[] ba = new byte[length];
                RNGCryptoServiceProvider.Create().GetBytes(ba);
                return ba;
            }
        }

    }

用法:

    using AESCrypto;

    ...
 public string DecryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

                byte[] bytesDecrypted = AESEncryption.AES_Decrypt(bytesToBeDecrypted, passwordBytes);

                string result = Encoding.UTF8.GetString(bytesDecrypted);

                return result;
            }

     private void btn1_Click(object sender, EventArgs e)
            {
                textBox1.Text = DecryptText("KEY_ENCRYPTED_WITH_PHP", "SomeSimpleTest");
            }

我甚至尝试使用CBC但不起作用......加密模式并不重要。我只想让它按预期工作。 感谢。

1 个答案:

答案 0 :(得分:2)

php代码:

[tid:com.facebook.react.JavaScript][RCTModuleData.mm:220] RCTBridge required dispatch_sync to load RCTDevSettings. This may lead to deadlocks

C#代码:

define('AES_128_ECB', 'aes-128-ecb');
$encryption_key = "MY_16_CHAR_KEY:)";
$data = "MyOwnEncryptedSecretText";
$encryptedData = openssl_encrypt($data, AES_128_ECB, $encryption_key, 0);

及其用法:

public String Decrypt(String text, String key)
{
    //decode cipher text from base64
    byte[] cipher = Convert.FromBase64String(text);
    //get key bytes
    byte[] btkey = Encoding.ASCII.GetBytes(key);

    //init AES 128
    RijndaelManaged aes128 = new RijndaelManaged();
    aes128.Mode = CipherMode.ECB;
    aes128.Padding = PaddingMode.PKCS7;

    //decrypt
    ICryptoTransform decryptor = aes128.CreateDecryptor(btkey, null);
    MemoryStream ms = new MemoryStream(cipher);
    CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);

    byte[] plain = new byte[cipher.Length];
    int decryptcount = cs.Read(plain, 0, plain.Length);

    ms.Close();
    cs.Close();

    //return plaintext in String
    return Encoding.UTF8.GetString(plain, 0, decryptcount);
}

现在它很棒:) 感谢。