2013-06-18 4 views
1

Rijndael 메서드를 사용하여 데이터를 암호화하고 해독하려고합니다. 암호를 해독하려고 시도하면 padding is invalid and cannot be removedcs.FlushFinalBlock();이고 private static byte[] DecryptString(byte[] cipherData, byte[] Key, byte[] IV) 방법입니다. 나는 심지어 중복이 공통 질문 알고있을 패딩이 잘못되어 제거 할 수 없습니다. cs.FlushFinalBlock() 라인에서 오류가 발생합니다

  • http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/0fa69204-3bba-48a9-9bdc-32a12b0da4a0
  • RijndaelManaged "Padding is invalid and cannot be removed" that only occurs when decrypting in production

  • Stopping decryption before EOF throws exception: Padding is invalid and cannot be removed
    • 처럼 많은 소스를 시도했다. 나는 아침부터 온라인에서 아무런 해결책도 찾지 못했습니다. 다음은 내 코드입니다.
      //clearText -> the string to be encrypted 
          //passowrd -> encryption key 
          public string EncryptString(string clearText, string Password) 
          { 
           // First we need to turn the input string into a byte array. 
           byte[] clearBytes = 
            Encoding.Unicode.GetBytes(clearText); 
      
           // Then, we need to turn the password into Key and IV 
           // We are using salt to make it harder to guess our key 
           // using a dictionary attack - 
           // trying to guess a password by enumerating all possible words. 
           var pdb = new PasswordDeriveBytes(Password, 
                    new byte[] 
                     { 
                      0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
                      0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 
                     }); 
      
           // Now get the key/IV and do the encryption using the 
           // function that accepts byte arrays. 
           // Using PasswordDeriveBytes object we are first getting 
           // 32 bytes for the Key 
           // (the default Rijndael key length is 256bit = 32bytes) 
           // and then 16 bytes for the IV. 
           // IV should always be the block size, which is by default 
           // 16 bytes (128 bit) for Rijndael. 
           // If you are using DES/TripleDES/RC2 the block size is 
           // 8 bytes and so should be the IV size. 
           // You can also read KeySize/BlockSize properties off 
           // the algorithm to find out the sizes. 
           byte[] encryptedData = EncryptString(clearBytes, 
                    pdb.GetBytes(32), pdb.GetBytes(16)); 
      
           // Now we need to turn the resulting byte array into a string. 
           // A common mistake would be to use an Encoding class for that. 
           //It does not work because not all byte values can be 
           // represented by characters. 
           // We are going to be using Base64 encoding that is designed 
           //exactly for what we are trying to do. 
           return Convert.ToBase64String(encryptedData); 
          } 
          //cipherText -> the string to be decrypted 
          //passowrd -> decryption key 
          public string DecryptString(string cipherText, string Password) 
          { 
           // First we need to turn the input string into a byte array. 
           // We presume that Base64 encoding was used 
           byte[] cipherBytes = Convert.FromBase64String(cipherText); 
      
           // Then, we need to turn the password into Key and IV 
           // We are using salt to make it harder to guess our key 
           // using a dictionary attack - 
           // trying to guess a password by enumerating all possible words. 
           var pdb = new PasswordDeriveBytes(Password, 
                    new byte[] 
                     { 
                      0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
                      0x64, 0x76, 0x65, 0x64, 0x65, 0x76 
                     }); 
      
           // Now get the key/IV and do the decryption using 
           // the function that accepts byte arrays. 
           // Using PasswordDeriveBytes object we are first 
           // getting 32 bytes for the Key 
           // (the default Rijndael key length is 256bit = 32bytes) 
           // and then 16 bytes for the IV. 
           // IV should always be the block size, which is by 
           // default 16 bytes (128 bit) for Rijndael. 
           // If you are using DES/TripleDES/RC2 the block size is 
           // 8 bytes and so should be the IV size. 
           // You can also read KeySize/BlockSize properties off 
           // the algorithm to find out the sizes. 
           byte[] decryptedData = DecryptString(cipherBytes, 
                    pdb.GetBytes(32), pdb.GetBytes(16)); 
      
           // Now we need to turn the resulting byte array into a string. 
           // A common mistake would be to use an Encoding class for that. 
           // It does not work 
           // because not all byte values can be represented by characters. 
           // We are going to be using Base64 encoding that is 
           // designed exactly for what we are trying to do. 
           return Encoding.Unicode.GetString(decryptedData); 
          } 
      
          // Encrypt a byte array into a byte array using a key and an IV 
          private static byte[] EncryptString(byte[] clearData, byte[] Key, byte[] IV) 
          { 
           // Create a MemoryStream to accept the encrypted bytes 
           var ms = new MemoryStream(); 
      
           // Create a symmetric algorithm. 
           // We are going to use Rijndael because it is strong and 
           // available on all platforms. 
           // You can use other algorithms, to do so substitute the 
           // next line with something like 
           //  TripleDES alg = TripleDES.Create(); 
           Rijndael alg = Rijndael.Create(); 
      
           // Now set the key and the IV. 
           // We need the IV (Initialization Vector) because 
           // the algorithm is operating in its default 
           // mode called CBC (Cipher Block Chaining). 
           // The IV is XORed with the first block (8 byte) 
           // of the data before it is encrypted, and then each 
           // encrypted block is XORed with the 
           // following block of plaintext. 
           // This is done to make encryption more secure. 
      
           // There is also a mode called ECB which does not need an IV, 
           // but it is much less secure. 
           alg.Key = Key; 
           alg.IV = IV; 
      
           // Create a CryptoStream through which we are going to be 
           // pumping our data. 
           // CryptoStreamMode.Write means that we are going to be 
           // writing data to the stream and the output will be written 
           // in the MemoryStream we have provided. 
           var cs = new CryptoStream(ms, 
                  alg.CreateEncryptor(), CryptoStreamMode.Write); 
      
           // Write the data and make it do the encryption 
           cs.Write(clearData, 0, clearData.Length); 
      
           // Close the crypto stream (or do FlushFinalBlock). 
           // This will tell it that we have done our encryption and 
           // there is no more data coming in, 
           // and it is now a good time to apply the padding and 
           // finalize the encryption process. 
           cs.FlushFinalBlock(); 
      
           // Now get the encrypted data from the MemoryStream. 
           // Some people make a mistake of using GetBuffer() here, 
           // which is not the right way. 
           byte[] encryptedData = ms.ToArray(); 
      
           return encryptedData; 
          } 
      
          private static byte[] DecryptString(byte[] cipherData, 
                   byte[] Key, byte[] IV) 
          { 
           // Create a MemoryStream that is going to accept the 
           // decrypted bytes 
           var ms = new MemoryStream(); 
      
           // Create a symmetric algorithm. 
           // We are going to use Rijndael because it is strong and 
           // available on all platforms. 
           // You can use other algorithms, to do so substitute the next 
           // line with something like 
           //  TripleDES alg = TripleDES.Create(); 
           Rijndael alg = Rijndael.Create(); 
      
           // Now set the key and the IV. 
           // We need the IV (Initialization Vector) because the algorithm 
           // is operating in its default 
           // mode called CBC (Cipher Block Chaining). The IV is XORed with 
           // the first block (8 byte) 
           // of the data after it is decrypted, and then each decrypted 
           // block is XORed with the previous 
           // cipher block. This is done to make encryption more secure. 
           // There is also a mode called ECB which does not need an IV, 
           // but it is much less secure. 
           alg.Key = Key; 
           alg.IV = IV; 
      
           // Create a CryptoStream through which we are going to be 
           // pumping our data. 
           // CryptoStreamMode.Write means that we are going to be 
           // writing data to the stream 
           // and the output will be written in the MemoryStream 
           // we have provided. 
           var cs = new CryptoStream(ms, 
                  alg.CreateDecryptor(), CryptoStreamMode.Write); 
      
           // Write the data and make it do the decryption 
           cs.Write(cipherData, 0, cipherData.Length); 
      
           // Close the crypto stream (or do FlushFinalBlock). 
           // This will tell it that we have done our decryption 
           // and there is no more data coming in, 
           // and it is now a good time to remove the padding 
           // and finalize the decryption process. 
           cs.FlushFinalBlock(); 
      
           // Now get the decrypted data from the MemoryStream. 
           // Some people make a mistake of using GetBuffer() here, 
           // which is not the right way. 
           byte[] decryptedData = ms.ToArray(); 
      
           return decryptedData; 
          } 
      

      은 대단히 감사합니다 :) PS : 내가

    답변

    1

    당신은 당신이 무슨 일이 일어나고 있는지 진단 할 수 있도록 예외 과거를 얻을 필요가 내 프로그램에 맞게 온라인에서이 코드를 잡고 약간 편집 에. 그렇게하기 위해서는 패딩을 예상하지 않기 위해서만 복호화 측을 설정해야합니다. 그렇게하면 아무 것도 받아 들일 수 있습니다. 일단 해독을하면 암호 해독에서 생겨나는 것을 살펴보고 결함 진단을 시작할 수 있습니다. 이것은 해결책이 아니라 예외를 무시하는 방법입니다. 예외의 원인은 무엇이든간에 여전히 존재합니다.

    무엇이 생겼는지보십시오. 모두 쓰레기입니까? 그것은 쓰레기의 일부분이고 원래의 평문을 구성합니까? 그것이 섞여 있다면, 쓰레기는 어디에 나타 납니까? 처음부터 끝까지, 둘 다 중간 어디 선가? 우리에게 당신이 보는 것을 말하면 문제의 가능한 원인을 알려줄 수 있습니다.

    모든 것이 제대로 작동하면 암호화 및 암호 해독을 모두 PKCS # 7 패딩으로 설정하십시오. 아니 패딩을 제자리에 두지 마십시오.

    +0

    안녕하세요 고맙습니다. 답장을 보내주세요. 내가 말한 단계를 시도하고 happns (y) 고맙습니다. :) –

    +0

    안녕하세요, 'PaddingMode.None'을 사용하면 올바른 결과를 얻을 수 있습니다. 하지만 패딩을 사용하여이 작업을 수행하는 방법. 통해 UR 제안, 패딩 그것은 필수 ryt 무엇입니까? –

    +0

    평문이 전체 바이트 수가 아닌 경우에는 여백이 필요합니다. 암호화와 암호 해독을 위해 패딩을 PKCS7 (또는 PKCS5)에 명시 적으로 설정하십시오. – rossum

    관련 문제