0

asp.net C#ファイルの暗号化/復号化プロセスを機能させるのに問題があります。ファイルをアップロードして暗号化することはできますが、復号化を機能させることができません。

エラーが発生します:Exception Details: System.Security.Cryptography.CryptographicException: Bad Data.復号化行で:

byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false);

これが私の暗号化機能です:

   private void EncryptFile(string inFile)
    {
        RijndaelManaged rjndl = new RijndaelManaged();
        rjndl.KeySize = 256;
        rjndl.BlockSize = 256;
        rjndl.Mode = CipherMode.CBC;
        ICryptoTransform transform = rjndl.CreateEncryptor();

        byte[] keyEncrypted = rsa.Encrypt(rjndl.Key, false);

        byte[] LenK = new byte[4];
        byte[] LenIV = new byte[4];

        int lKey = keyEncrypted.Length;
        LenK = BitConverter.GetBytes(lKey);
        int lIV = rjndl.IV.Length;
        LenIV = BitConverter.GetBytes(lIV);

        int startFileName = inFile.LastIndexOf("\\") + 1;
        // Change the file's extension to ".enc"
        string outFile = EncrFolder + inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + ".enc";

        lblDecryptFileName.Text = outFile;

        using (FileStream outFs = new FileStream(outFile, FileMode.Create))
        {
            outFs.Write(LenK, 0, 4);
            outFs.Write(LenIV, 0, 4);
            outFs.Write(keyEncrypted, 0, lKey);
            outFs.Write(rjndl.IV, 0, lIV);

            using (CryptoStream outStreamEncrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
            {
                int count = 0;
                int offset = 0;
                int blockSizeBytes = rjndl.BlockSize / 8;
                byte[] data = new byte[blockSizeBytes];
                int bytesRead = 0;
                using (FileStream inFs = new FileStream(inFile, FileMode.Open))
                {
                    do
                    {
                        count = inFs.Read(data, 0, blockSizeBytes);
                        offset += count;
                        outStreamEncrypted.Write(data, 0, count);
                        bytesRead += blockSizeBytes;
                    }
                    while (count > 0);
                    inFs.Close();
                }
                outStreamEncrypted.FlushFinalBlock();
                outStreamEncrypted.Close();
            }
            outFs.Close();
        }

    }

そして、これがエラーが発生した復号化機能です。

   private void DecryptFile(string inFile)
    {

        // Create instance of Rijndael for
        // symetric decryption of the data.
        RijndaelManaged rjndl = new RijndaelManaged();
        rjndl.KeySize = 256;
        rjndl.BlockSize = 256;
        rjndl.Mode = CipherMode.CBC;
        byte[] LenK = new byte[4];
        byte[] LenIV = new byte[4];
        string outFile = DecrFolder + inFile.Substring(0, inFile.LastIndexOf(".")) + ".txt";

        using (FileStream inFs = new FileStream(EncrFolder + inFile, FileMode.Open))
        {

            inFs.Seek(0, SeekOrigin.Begin);
            inFs.Seek(0, SeekOrigin.Begin);
            inFs.Read(LenK, 0, 3);
            inFs.Seek(4, SeekOrigin.Begin);
            inFs.Read(LenIV, 0, 3);

            int lenK = BitConverter.ToInt32(LenK, 0);
            int lenIV = BitConverter.ToInt32(LenIV, 0);
            int startC = lenK + lenIV + 8;
            int lenC = (int)inFs.Length - startC;

            // Create the byte arrays for
            // the encrypted Rijndael key,
            // the IV, and the cipher text.
            byte[] KeyEncrypted = new byte[lenK];
            byte[] IV = new byte[lenIV];

            // Extract the key and IV
            // starting from index 8
            // after the length values.
            inFs.Seek(8, SeekOrigin.Begin);
            inFs.Read(KeyEncrypted, 0, lenK);
            inFs.Seek(8 + lenK, SeekOrigin.Begin);
            inFs.Read(IV, 0, lenIV);
            Directory.CreateDirectory(DecrFolder);

            byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false);

            ICryptoTransform transform = rjndl.CreateDecryptor(KeyDecrypted, IV);

            using (FileStream outFs = new FileStream(outFile, FileMode.Create))
            {

                int count = 0;
                int offset = 0;

                int blockSizeBytes = rjndl.BlockSize / 8;
                byte[] data = new byte[blockSizeBytes];

                inFs.Seek(startC, SeekOrigin.Begin);
                using (CryptoStream outStreamDecrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
                {
                    do
                    {
                        count = inFs.Read(data, 0, blockSizeBytes);
                        offset += count;
                        outStreamDecrypted.Write(data, 0, count);

                    }
                    while (count > 0);

                    outStreamDecrypted.FlushFinalBlock();
                    outStreamDecrypted.Close();
                }
                outFs.Close();
            }
            inFs.Close();
        }

    }

これに関するどんな助けも素晴らしいでしょう!私はRSA暗号化の専門家ではなく、多くの投稿を読んでいますが、それでも解決策を思い付くことができません。

4

1 に答える 1

1

私はついにこれを理解しました。デスクトップアプリケーションで試してみたところ、コードはうまく機能しました。私が書き込もうとしていたasp.net4Webアプリケーションでは機能しませんでした。問題は、RSAオブジェクトがセッションを通じて永続化されなかったことです。したがって、RSAオブジェクトは正常に作成されました。ファイルは大丈夫暗号化されました。しかし、ファイルを復号化しようとしたとき、RSAオブジェクトはそこにありませんでした。のエラーメッセージSystem.Security.Cryptography.CryptographicException: Bad Dataは誤解を招く可能性があります。これは実際には問題ではなく、データは問題ありませんでした。

したがって、キーとRSAオブジェクトを作成するときに、次のものを使用しました。

rsa = new RSACryptoServiceProvider(cspp);
Session["rsa"] = rsa;

次に、復号化関数が呼び出されたときに、次を追加しました。

if (rsa == null)
     rsa = (RSACryptoServiceProvider)Session["rsa"];

もちろん、これにはもう少しコードがありますので、RSAセッションのキーがない場合はキャッチしてください。ただし、これは私が抱えていた問題の高レベルの解決策です。

誰かがこれを探しているなら、私に知らせてください、そして私はより多くのコードを共有することができます。

于 2012-10-25T12:35:42.410 に答える