none
"Bad Dada" When Call RSACryptoServiceProvider.Decrypt Method on Some Machine RRS feed

  • Question

  • Hi, 

    I have written a small Windows program and a setup project. I could run the msi file created by the setup on my machine, and decrypt perfectly. I have also successfully installed the program on other machine. But when I run the the program to decrypt a file, I got an exception. 

    My machine has VS 2005 installed. The other machine is a XP machine with sp2. So something different in the Evironment caused the issue.

    Here is the exception detail:

    Caught an expected exception:
    System.Security.Cryptography.CryptographicException: Bad Data.

       at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
       at System.Security.Cryptography.Utils._DecryptKey(SafeKeyHandle hPubKey, Byte[] key, Int32 dwFlags)
       at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
       at loganalyzer.utilityForm.DecryptFile(String inFile, String outFile)


    Properties of the exception are as follows:
    Message: Bad Data.

    Source: mscorlib
    Stack trace:    at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
       at System.Security.Cryptography.Utils._DecryptKey(SafeKeyHandle hPubKey, Byte[] key, Int32 dwFlags)
       at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
       at loganalyzer.utilityForm.DecryptFile(String inFile, String outFile)
    Help link:
    Target site's name: ThrowCryptogaphicException
    Base exception message: Bad Data.


    Here is the related code:

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

     BinaryReader br = new BinaryReader(inFs, Encoding.Unicode);
     BinaryWriter bw = new BinaryWriter(outFs, Encoding.Unicode);

     int blockSizeBytes = 128;
     byte[] data = new byte[blockSizeBytes];
     byte[] decrypted;
     int count = 0;

     while ((count = br.Read(data, 0, blockSizeBytes)) > 0)
     {
      log(string.Format("read {0} bytes from source file", count));
      try
      {
       decrypted = rsa.Decrypt(data, false);
      }
      catch (CryptographicException ex)
      {  
        ...
       return false;
      }

      bw.Write(decrypted, 0, decrypted.Length);
     }
     outFs.Close();
     inFs.Close();
    }

    I have tried with Encoding.ASCII, and default for BinaryReader construct, but turned out the same error.

    I have seen quite a few threads in the forum, but did not find a solution for my issue. I would appreciate any suggestion.

    Thanks!

    Friday, July 4, 2008 3:38 PM

Answers

  • Hi Junbin,

    This might not be the issue, but if I were de/encrypting to file I wouldn't use any kind of encoding.  Both the file system and RSA deal with raw bytes so you should be able to read and write to the fileStream without any BinaryReader/Writer.

    Here's some code that works for me.  It just encrypts and then decrypts a file.  I'm not sure if I ever ran it on XP put it works on Vista, WinSrv2008 and WinSrv2003.  It's only test code but I hope it helps:

    1using System; 
    2using System.IO; 
    3using System.Security.Cryptography; 
    4 
    5namespace Test 
    6
    7    class RsaTest 
    8    { 
    9        static string baseDir = @"C:\Somewhere\"
    10 
    11        static void Main(string[] args) 
    12        { 
    13            RSACryptoServiceProvider keyProvider = new RSACryptoServiceProvider(); 
    14            RSAParameters privateParamaters = keyProvider.ExportParameters(true); 
    15            RSAParameters publicParamaters = keyProvider.ExportParameters(false); 
    16             
    17            string inFile = baseDir + "InFile.test"
    18            string encFile = baseDir + "EncFile.test"
    19            string outFile = baseDir + "OutFile.test"
    20            
    21            bool doOaepPadding = false
    22 
    23            //Encrypt File:  inFile -> encFile 
    24            using (FileStream inStream = new FileStream(inFile, FileMode.Open), encStream = new FileStream(encFile, FileMode.Create))             
    25                EncryptStream(inStream, encStream, publicParamaters, doOaepPadding); 
    26             
    27            //Decrypt File:  encFile -> outFile 
    28            using (FileStream encStream = new FileStream(encFile, FileMode.Open), outStream = new FileStream(outFile, FileMode.Create))             
    29                DecryptStream(encStream, outStream, privateParamaters, doOaepPadding);             
    30        } 
    31 
    32        static void EncryptStream(Stream inStream, Stream encStream, RSAParameters paramaters, bool doOaepPadding) 
    33        { 
    34            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
    35            rsa.ImportParameters(paramaters); 
    36 
    37            int readBlockSize = doOaepPadding ? 86 : 117; 
    38 
    39            byte[] readBlock = new byte[readBlockSize]; 
    40            int count; 
    41            while ((count = inStream.Read(readBlock, 0, readBlockSize)) > 0) 
    42            { 
    43                byte[] blockToEncrypt; 
    44                if (count == readBlockSize) 
    45                    blockToEncrypt = readBlock; 
    46                else 
    47                    Array.Copy(readBlock, blockToEncrypt = new byte[count], count); 
    48                 
    49                byte[] encryptedBlock = rsa.Encrypt(blockToEncrypt, doOaepPadding); 
    50                if (encryptedBlock.Length != 128) 
    51                    throw new Exception("Didn't Expect This!"); 
    52                encStream.Write(encryptedBlock, 0, encryptedBlock.Length); 
    53            } 
    54        } 
    55 
    56        static void DecryptStream(Stream encStream, Stream outStream, RSAParameters paramaters, bool doOaepPadding) 
    57        { 
    58            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
    59            rsa.ImportParameters(paramaters); 
    60 
    61            int blockToDecryptSize = 128; 
    62 
    63            byte[] blockToDecrypt = new byte[blockToDecryptSize]; 
    64            int count; 
    65            while ((count = encStream.Read(blockToDecrypt, 0, blockToDecryptSize)) > 0) 
    66            { 
    67                if (count != blockToDecryptSize) 
    68                    throw new Exception("Didn't Expect This!"); 
    69 
    70                byte[] decryptedBlock = rsa.Decrypt(blockToDecrypt, doOaepPadding); 
    71                outStream.Write(decryptedBlock, 0, decryptedBlock.Length); 
    72            } 
    73        } 
    74          
    75    } 
    76
    77 


    Good luck,

    John
    • Marked as answer by Junbin Duan Tuesday, July 8, 2008 2:21 PM
    • Marked as answer by Junbin Duan Tuesday, July 8, 2008 2:21 PM
    Saturday, July 5, 2008 6:59 PM

All replies

  • Hi Junbin,

    This might not be the issue, but if I were de/encrypting to file I wouldn't use any kind of encoding.  Both the file system and RSA deal with raw bytes so you should be able to read and write to the fileStream without any BinaryReader/Writer.

    Here's some code that works for me.  It just encrypts and then decrypts a file.  I'm not sure if I ever ran it on XP put it works on Vista, WinSrv2008 and WinSrv2003.  It's only test code but I hope it helps:

    1using System; 
    2using System.IO; 
    3using System.Security.Cryptography; 
    4 
    5namespace Test 
    6
    7    class RsaTest 
    8    { 
    9        static string baseDir = @"C:\Somewhere\"
    10 
    11        static void Main(string[] args) 
    12        { 
    13            RSACryptoServiceProvider keyProvider = new RSACryptoServiceProvider(); 
    14            RSAParameters privateParamaters = keyProvider.ExportParameters(true); 
    15            RSAParameters publicParamaters = keyProvider.ExportParameters(false); 
    16             
    17            string inFile = baseDir + "InFile.test"
    18            string encFile = baseDir + "EncFile.test"
    19            string outFile = baseDir + "OutFile.test"
    20            
    21            bool doOaepPadding = false
    22 
    23            //Encrypt File:  inFile -> encFile 
    24            using (FileStream inStream = new FileStream(inFile, FileMode.Open), encStream = new FileStream(encFile, FileMode.Create))             
    25                EncryptStream(inStream, encStream, publicParamaters, doOaepPadding); 
    26             
    27            //Decrypt File:  encFile -> outFile 
    28            using (FileStream encStream = new FileStream(encFile, FileMode.Open), outStream = new FileStream(outFile, FileMode.Create))             
    29                DecryptStream(encStream, outStream, privateParamaters, doOaepPadding);             
    30        } 
    31 
    32        static void EncryptStream(Stream inStream, Stream encStream, RSAParameters paramaters, bool doOaepPadding) 
    33        { 
    34            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
    35            rsa.ImportParameters(paramaters); 
    36 
    37            int readBlockSize = doOaepPadding ? 86 : 117; 
    38 
    39            byte[] readBlock = new byte[readBlockSize]; 
    40            int count; 
    41            while ((count = inStream.Read(readBlock, 0, readBlockSize)) > 0) 
    42            { 
    43                byte[] blockToEncrypt; 
    44                if (count == readBlockSize) 
    45                    blockToEncrypt = readBlock; 
    46                else 
    47                    Array.Copy(readBlock, blockToEncrypt = new byte[count], count); 
    48                 
    49                byte[] encryptedBlock = rsa.Encrypt(blockToEncrypt, doOaepPadding); 
    50                if (encryptedBlock.Length != 128) 
    51                    throw new Exception("Didn't Expect This!"); 
    52                encStream.Write(encryptedBlock, 0, encryptedBlock.Length); 
    53            } 
    54        } 
    55 
    56        static void DecryptStream(Stream encStream, Stream outStream, RSAParameters paramaters, bool doOaepPadding) 
    57        { 
    58            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
    59            rsa.ImportParameters(paramaters); 
    60 
    61            int blockToDecryptSize = 128; 
    62 
    63            byte[] blockToDecrypt = new byte[blockToDecryptSize]; 
    64            int count; 
    65            while ((count = encStream.Read(blockToDecrypt, 0, blockToDecryptSize)) > 0) 
    66            { 
    67                if (count != blockToDecryptSize) 
    68                    throw new Exception("Didn't Expect This!"); 
    69 
    70                byte[] decryptedBlock = rsa.Decrypt(blockToDecrypt, doOaepPadding); 
    71                outStream.Write(decryptedBlock, 0, decryptedBlock.Length); 
    72            } 
    73        } 
    74          
    75    } 
    76
    77 


    Good luck,

    John
    • Marked as answer by Junbin Duan Tuesday, July 8, 2008 2:21 PM
    • Marked as answer by Junbin Duan Tuesday, July 8, 2008 2:21 PM
    Saturday, July 5, 2008 6:59 PM
  • Thank you John,

    It works well now. Thank you very much for the help!

    Junbin
    Tuesday, July 8, 2008 2:21 PM