0

I was trying to encrypt my hello.txt file but it failed. When I encrypt, this is the exception:

System.UnauthorizedAccessException: Access to the path 'C:\Users\username\Desktop' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
at Encrypt.EncDec.Decrypt(String fileIn, String fileOut, String Password) in C:\Users\username\Documents\My Apps\Encrypt\Encrypt\Form1.cs:line 518
at Encrypt.Form1.proceedEDfe(String input, String output, String key) in C:\Users\username\Documents\My Apps\Encrypt\Encrypt\Form1.cs:line 154

So here is my code (line 154):

string inputE;
string outputE;
string pwdE;

private void ofd1_Click(object sender, EventArgs e)
{
    if (ofd.ShowDialog() == DialogResult.OK)
    {
        inputE = ofd.FileName;
    }
}

private void fbd1_Click(object sender, EventArgs e)
{
    if(fbd.ShowDialog() == DialogResult.OK)
    {
        outputE = fbd.SelectedPath;
    }
}

private void encryptF_Click(object sender, EventArgs e)
{
    pwdE = keyE.Text;
    if (inputE != null && outputE != null && pwdE != null)
    {
        proceedEDfe(inputE, outputE, pwdE);
    }
}

private void proceedEDfe(string input, string output, string key)
{
    try
    {
        EncDec.Decrypt(input, output, key); //line 154
        doneStat.Text = "File decryption succeeded";
    }
    catch (Exception ex)
    {
        doneStat.Text = "File decryption failed";
        MessageBox.Show(Convert.ToString(ex), "Error");
        doneStatTb.Text = Convert.ToString(ex);
    }
}

I copied this code from Code Project, the EncDec class Decrypt method is this (line 518):

// Decrypt a file into another file using a password 
public static void Decrypt(string fileIn, string fileOut, string Password)
{

    FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read);
    //line 518
    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(); 
    fsIn.Close();
}

How should I fix this? Is there something wrong in the code?

Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
newbieguy
  • 658
  • 2
  • 11
  • 29
  • Is this a learning exercise? Because it's important to note that **cryptography is really hard to do properly**, and if you're writing your own encryption algorithms (or reimplementing someone else's) for anything outside of a learning exercise and you don't already have a solid background in the field, you are setting yourself up for big, big problems down the line. – Daniel Mann Jun 13 '15 at 13:45

2 Answers2

0

You got System.IO exception there is nothing to do with encryption...

Check this link to handle it:

Why is access to the path denied?

Community
  • 1
  • 1
User1234
  • 510
  • 3
  • 20
0

You have specified C:\Users\username\Desktop as the name of either the input file or the output file. This is of course a directory, and the error is saying that you can't read from or write to this directory as if it were a file.

It appears you are using a FolderBrowserDialog for selecting the output. This dialog of course only selects directories. What I imagine you want to do is take the filename of the input file and append that to the output directory. So if your input file is C:\Users\username\Input\somefile.txt, you would want the output file to be C:\Users\username\Desktop\somefile.txt. In which case, you would use Path.GetFileName to get the filename of the input file (i.e. the somefile.txt part), and use Path.Combine to join this to the output directory.

I made these changes to your encryptF_Click method to give me the following:

private void encryptF_Click(object sender, EventArgs e)
{
    pwdE = keyE.Text;
    if (inputE != null && outputE != null && pwdE != null)
    {
        string outputFile = Path.Combine(outputE, Path.GetFileName(inputE));
        proceedEDfe(inputE, outputFile, pwdE);
    }
}
Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
  • i should check `inputE` and `outputE` strings? – newbieguy Jun 13 '15 at 13:18
  • @cromix: I've now realised that your `fbd` is quite probably a FolderBrowserDialog, so it's the output that's the problem, not the input file. Essentially you're choosing a directory to write the output to but not telling Windows what you want the name of the file within this directory to be. – Luke Woodward Jun 13 '15 at 13:49
  • an exception appeared: `System.IO.IOException: The process cannot access the file 'D:\hello.txt' because it is being used by another process.` – newbieguy Jun 13 '15 at 13:56
  • The `Decrypt` method doesn't close `fsOut`, which I can't imagine helps. At the very least, add a call to `fsOut.Close()` to the bottom of that method. Better, ensure that the streams are closed by opening them inside `using` statements. If you are also using the `Encrypt` method from that CodeProject sample, close `fsOut` within that too. This might cause your encrypted files to not be written to disk fully and hence fail to decrypt. – Luke Woodward Jun 13 '15 at 14:08
  • the `cs.Close();` will close the unrelying fsOut stream – newbieguy Jun 13 '15 at 14:15
  • Try calling the `Dispose()` method on the streams, instead of the `Close()` method. The `CryptoStream`s might not be flushing all the data out if you don't `Dispose()` of them. Better yet, use `using` statements to handle the streams, as I've already suggested. Be aware that that CodeProject code is very old (2003) and so was quite probably written before `using` statements were added. – Luke Woodward Jun 13 '15 at 21:19
  • Thanks btw, I already solved the problem/exception: `System.IO.IOException: The process cannot access the file 'D:\hello.txt' because it is being used by another process.` The input file and the output file have the same filename so what i did is `Path.Combine(outputDir, Path.Getfilenamewithoutextension(inputfile) + "-encrypted" + Path.GetExtension(inputfile))` – newbieguy Jun 14 '15 at 00:32