使用phpseclib复制C#RIjndael加密

使用phpseclib复制C#RIjndael加密,c#,php,encryption,C#,Php,Encryption,我有一个C#类(见下文)。接收者使用它来加密/解密我的消息。我正在尝试使用加密/解密,但无法为接收方成功加密/解密。 phpseclib的正确实现是什么 using System; using System.IO; using System.Security.Cryptography; public class EncDec { public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV) {

我有一个C#类(见下文)。接收者使用它来加密/解密我的消息。我正在尝试使用加密/解密,但无法为接收方成功加密/解密。 phpseclib的正确实现是什么

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

public class EncDec
{
    public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)
    {
        MemoryStream ms = new MemoryStream();
        Rijndael alg = Rijndael.Create();

        alg.Key = Key;
        alg.IV = IV;

       CryptoStream cs = new CryptoStream(ms,
       alg.CreateEncryptor(), CryptoStreamMode.Write);

       cs.Write(clearData, 0, clearData.Length);
       cs.Close();

       byte[] encryptedData = ms.ToArray();

       return encryptedData;
   }

public static string Encrypt(string clearText, string Password)
{
    byte[] clearBytes =
      System.Text.Encoding.Unicode.GetBytes(clearText);


        new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
        0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

    byte[] encryptedData = Encrypt(clearBytes,
             pdb.GetBytes(32), pdb.GetBytes(16));

    return Convert.ToBase64String(encryptedData);
}

public static byte[] Encrypt(byte[] clearData, string Password)
{
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
        new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
        0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

    return Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16));

}

public static void Encrypt(string fileIn,
            string fileOut, string Password)
{

    FileStream fsIn = new FileStream(fileIn,
        FileMode.Open, FileAccess.Read);
    FileStream fsOut = new FileStream(fileOut,
        FileMode.OpenOrCreate, FileAccess.Write);

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
        new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
        0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

    Rijndael alg = Rijndael.Create();
    alg.Key = pdb.GetBytes(32);
    alg.IV = pdb.GetBytes(16);

    CryptoStream cs = new CryptoStream(fsOut,
        alg.CreateEncryptor(), CryptoStreamMode.Write);

    int bufferLen = 4096;
    byte[] buffer = new byte[bufferLen];
    int bytesRead;

    do
    {
        bytesRead = fsIn.Read(buffer, 0, bufferLen);
        cs.Write(buffer, 0, bytesRead);
    } while (bytesRead != 0);

    cs.Close();
    fsIn.Close();
}

public static byte[] Decrypt(byte[] cipherData,
                            byte[] Key, byte[] IV)
{
    MemoryStream ms = new MemoryStream();

    Rijndael alg = Rijndael.Create();

    alg.Key = Key;
    alg.IV = IV;

    CryptoStream cs = new CryptoStream(ms,
        alg.CreateDecryptor(), CryptoStreamMode.Write);

    cs.Write(cipherData, 0, cipherData.Length);
    cs.Close();

    byte[] decryptedData = ms.ToArray();
    return decryptedData;
}

public static string Decrypt(string cipherText, string Password)
{

    byte[] cipherBytes = Convert.FromBase64String(cipherText);

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
        new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
        0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

    byte[] decryptedData = Decrypt(cipherBytes,
        pdb.GetBytes(32), pdb.GetBytes(16));

    return System.Text.Encoding.Unicode.GetString(decryptedData);
}

public static byte[] Decrypt(byte[] cipherData, string Password)
{        
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
        new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
        0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

    return Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16));
}

public static void Decrypt(string fileIn,
            string fileOut, string Password)
{
    FileStream fsIn = new FileStream(fileIn,
                FileMode.Open, FileAccess.Read);
    FileStream fsOut = new FileStream(fileOut,
                FileMode.OpenOrCreate, FileAccess.Write);

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
        new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
        0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
       Rijndael alg = Rijndael.Create();

       alg.Key = pdb.GetBytes(32);
        alg.IV = pdb.GetBytes(16);

        CryptoStream cs = new CryptoStream(fsOut,
        alg.CreateDecryptor(), CryptoStreamMode.Write);

    int bufferLen = 4096;
    byte[] buffer = new byte[bufferLen];
    int bytesRead;

    do
    {
        bytesRead = fsIn.Read(buffer, 0, bufferLen);
        cs.Write(buffer, 0, bytesRead);

    } while (bytesRead != 0);

    cs.Close(); // this will also close the unrelying fsOut stream 
    fsIn.Close();
}
}
这是一个phpseclib示例

 $rijndael = new \phpscelib\Crypt\Rijndael();
 $rijndael->setKey($encryption_password);

 $clear_text = $rijndael->decrypt($cipher_text);
 $cipher_text = $rijndael->encrypt($clear_text);
两(或三)个关键问题:

  • 您没有在php端设置IV
  • 您可以从c代码中的密码派生密钥。对于php代码,您不需要(您直接使用密码作为密钥)
  • 在c#中使用Base64对密码字节进行编码。php库似乎没有做到这一点,尽管我可能有错
安全问题:

  • 您正在对PasswordDeriveBytes使用固定的salt。考虑生成密码学随机盐并将其添加到密文中。如果你想知道原因,这里有很多很好的答案
  • 直接使用明文密码/短语进行加密(如在php代码中)被认为是不安全的。加密密钥应该是随机的。密码哈希算法的输出正常

您可能缺少php端的IV。此外,如果您是从密码派生Rijndael密钥,请确保使用相同的算法和相同的salt。让我试试您的建议。