1

我在我的服务器端代码中使用了 Rijndael(加密算法),它是用 C 语言编写的。但是我的客户端是用 C# 编写的,C# 提供了自己的 Rijndael 类来加密和解密。

在客户端,我使用相同的密码生成密钥,但客户端应用程序无法解密它。我想在 C 中加密文件并在 .NET (C#) 中解密该文件。

服务器代码:http ://www.efgh.com/software/rijndael.txt

客户代码:

    public static void Encrypt()
    {

        string password = @"4c696e6775614e6578742431302a4c6f63616c697a6174696f6e2a3949505f3030372a"; // Your Key Here
            /*UnicodeEncoding UE = new UnicodeEncoding();
            byte[] key = UE.GetBytes(password);*/
            Rfc2898DeriveBytes  pdb = new Rfc2898DeriveBytes (password, new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c });

            string cryptFile = @"F:\Encoding and Decoding\ReadMe_Encrypted.txt";
            FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

            RijndaelManaged RMCrypto = new RijndaelManaged();
            RMCrypto.KeySize = 256;
            RMCrypto.BlockSize = 256;               
            byte[] key = pdb.GetBytes(RMCrypto.KeySize / 8);
            byte[] iv = pdb.GetBytes(RMCrypto.BlockSize / 8);  
            CryptoStream cs = new CryptoStream(fsCrypt,
                RMCrypto.CreateEncryptor(key, iv),
                CryptoStreamMode.Write);

            FileStream fsIn = new FileStream(@"F:\Encoding and Decoding\ReadMe.txt", FileMode.Open);

            int data;
            while ((data = fsIn.ReadByte()) != -1)
                cs.WriteByte((byte)data);

            fsIn.Close();
            cs.Close();
            fsCrypt.Close();

    }
    public static void Decrypt()
    {
        string password = @"4c696e6775614e6578742431302a4c6f63616c697a6174696f6e2a3949505f3030372a"; // Your Key Here

       /* UnicodeEncoding UE = new UnicodeEncoding();
        byte[] key = UE.GetBytes(password);*/
       // PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c });
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c });

        FileStream fsCrypt = new FileStream(@"F:\Encoding and Decoding\ReadMe_Encrypted.txt", FileMode.Open);

        RijndaelManaged RMCrypto = new RijndaelManaged();
        RMCrypto.KeySize = 256;
        RMCrypto.BlockSize = 256;
        byte[] key = pdb.GetBytes(RMCrypto.KeySize / 8);
        byte[] iv = pdb.GetBytes(RMCrypto.BlockSize /8);  
        CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, iv), CryptoStreamMode.Read);
     //   CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(), CryptoStreamMode.Read);


        FileStream fsOut = new FileStream(@"F:\Encoding and Decoding\ReadMe_Decrypted.txt", FileMode.Create);

        int data;
        while ((data = cs.ReadByte()) != -1)
            fsOut.WriteByte((byte)data);

        fsOut.Close();
        cs.Close();
        fsCrypt.Close();
    }
4

1 回答 1

2

在 C# 代码中,您Rfc2898DeriveBytes用于将密码字符串转换为 256 位密钥(实际上,这实际上是使用 SHA-1 对密码进行哈希处理),而在 C 代码中,您直接使用密钥。您可能想修改 C# 代码以直接使用密钥(对我来说,它看起来像一个 256 位密钥,而不是 ASCII 密码)。

以下内容就足够了:

byte[] key = {0x4c, 0x69, 0x6e, 0x67, ...};

您还需要修改 C 程序以使用正确的二进制密钥,而不是在命令行上使用一个。您可以使用以下内容:

unsigned char key[KEYLENGTH(KEYBITS)] = {0x4c, 0x69, 0x6e, 0x67, ...};

我也不确定您是否使用相同的模式(http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation)。我认为 C# 代码可能使用 CBC,而 C 代码使用 ECB。我建议这样做,因为 C# 代码中有一个 iv(从密码生成),但 C 代码中没有。

您也可以尝试找到一个可以从 C 和 C# 中使用的库,然后改用它,例如 openssl。

于 2012-08-08T07:13:16.187 回答