2017-01-17 25 views
0

私はCryptoJsを使用してJavaScriptでクライアント側のファイルの暗号化を持っています。私はRijndaelManagedを使用してサーバー側のファイル解読を行っています。 CryptoJsを使用して暗号化と復号化の両方を行うと、正常に動作しています。しかし、私はC#コードを使用して解読しようとすると、以下のエラーを投げています。私は別のパディング、モードなどを無駄に設定しようとしました。CryptoJs暗号化とRijndaelManagedを使用したC#暗号化 - エラー

CryptographicException length of the data to decrypt is invalid 

CRyptoJSコード:

function encryptFile() { 
selectedFiles = document.getElementById("MainContent_fileinput"); 

$.each(selectedFiles.files, function (i, file) { 
    var reader = new FileReader(); 
    var strKey = " "; 
    var strIv = " "; 
    var byteArrKey = [169,204,147,221,70,76,207,92,102,12,237,65,5,205,34,106,178,141,138,117,224,153,37,124,54,17,74,223,224,153,72,209]; 
    var byteArrIV = [169,204,147,221,70,76,207,92,102,12,237,65,5,205,34,106]; 
    var byteVal; 
    var byteValIv; 

    reader.onloadend = function (e) { 
     for (var i = 0; i < byteArrKey.length; i++) { 
      byteVal = byteArrKey[i]; 
      if (byteVal < 16) { strKey += "0"; } 
      strKey += byteVal.toString(16); 
     }; 
     for (var i = 0; i < byteArrIV.length; i++) { 
      byteValIv = byteArrIV[i]; 
      //if (byteValIv < 16) { strIv += "0"; } 
      strIv += byteVal.toString(16); 
     }; 
     var encrypted1 = CryptoJS.AES.encrypt(reader.result, strKey, { 'iv': strIv }); 
     //   var encrypted1 = CryptoJS.AES.encrypt(reader.result, key, 
     //        { keySize: 128/8, iv: iv1, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); 

     var ct1 = encrypted1.toString(); 
     var encodedData1 = window.btoa(ct1); 
     $.ajax({ 
      async: 'true', 
      url: "MYWEBSERVICE URL", 
      method: "POST", 
      processData: 'false', 
      headers: { 
       'content-type': "application/x-www-form-urlencoded", 
       'cache-control': "no-cache" 
      }, 
      data: { 'folderPath': folderPath, 'uploadData': encodedData1, 'fileName': file.name + '.encrypted' }, 

      success: function (response) { 
       debugger; 
       console.log(response); 
      }, 
      error: function (xhr, textStatus, error) { 
       debugger; 
       console.log(xhr.statusText); 
      } 
     }); 
    }; 
    reader.readAsDataURL(file); 
}) 
} 

C#を使用して復号化:

private static byte[] CreateKey(string pwd) 
{ 
    byte[] bytKey; 
    byte[] bytSalt = Encoding.ASCII.GetBytes(pwd); 
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, bytSalt); 
    bytKey = pdb.GetBytes(32); 
    return bytKey; 
} 

private static byte[] CreateIV(string pwd) 
{ 
    byte[] bytIV; 
    byte[] bytSalt = Encoding.ASCII.GetBytes(pwd); 
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, bytSalt); 
    bytIV = pdb.GetBytes(16); 
    return bytIV; 
}  

private static bool DecryptFile(string strInputFile, string strOutputFile) 
{ 
    bool returnValue = true; 
FileStream fsInput = null; 
FileStream fsOutput = null; 
Int32 intBytesInCurrentBlock; 
CryptoStream csCryptoStream = null; 

byte[] bytBuffer; // = new byte[fsInput.Length]; 

bytKey = CreateKey("123456"); 
bytIV = CreateIV("123456"); 

try 
{ 

    using (var fsInput = File.OpenRead(strInputFile)) 
      using (var fsOutput = File.Create(strOutputFile)) 
      using (Aes aes = Aes.Create()) 
      using (ICryptoTransform decryptor = aes.CreateDecryptor(bytKey, bytIV)) 
      using (var decryptionStream = new CryptoStream(fsOutput, decryptor, CryptoStreamMode.Write)) 
      using (var base64Decode = new FromBase64Transform()) 
      using (var cryptoStream = new CryptoStream(decryptionStream, base64Decode, CryptoStreamMode.Write)) 
      { 
       fsInput.CopyTo(cryptoStream); 
       cryptoStream.Dispose(); 
       cryptoStream.FlushFinalBlock(); 
       decryptionStream.Dispose(); 
       decryptionStream.FlushFinalBlock(); 
      } 
} 
catch 
{ 
    throw; 
} 
finally 
{ 
    csCryptoStream.Close(); 
    fsInput.Close(); 
    fsOutput.Close(); 
} 
return returnValue; 
} 

WebServiceの方法:

byte[] byteUploadFile = Convert.FromBase64String(uploadData); 
BinaryWriter binWriter = new   BinaryWriter(File.Open(Path.Combine(folderPath, fileName), FileMode.Create, FileAccess.ReadWrite)); 
binWriter.Write(byteUploadFile); 
binWriter.Close(); 

答えて

0

:CryptoJSを使用して

ファイルの暗号化:C#を使用して

function esp() { 
    selectedFiles = document.getElementById("MainContent_file1"); 
    var sfile = selectedFiles.files[0]; 
    var read = new FileReader(); 
    read.onload = function (e) { 
     var key = CryptoJS.enc.Utf8.parse('7061737323313233'); 
     var iv = CryptoJS.enc.Utf8.parse('7061737323313233'); 
     var encrypted = CryptoJS.AES.encrypt(reader.result, key, { keySize: 128/8, iv: iv, 
      mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 
     }); 
     var ct = encrypted.toString(); 
     debugger; 
     $.ajax({ 
      async: 'true', 
      url: "http://localhost:51936/WebService1.asmx/FileUpload", 
      method: "POST", 
      processData: 'false', 
      headers: { 
       'content-type': "application/json", 
       'cache-control': "no-cache" 
      }, 
      data: JSON.stringify({ 'folderPath': folderPath, 'uploadData': ct, 'fileName': sfile.name + '.encrypted' }), 
      success: function (response) { 
       console.log(response); 
      }, 
      error: function (xhr, textStatus, error) { 
       console.log(xhr.statusText); 
      } 
     }); 
    } 
    read.readAsDataURL(sfile); 
} 

復号化:

[WebMethod] 
public void Decrypt(object sender, EventArgs e) 
{ 
    string folderPath = "path"; 
    DirectoryInfo d = new DirectoryInfo(folderPath).GetDirectories().OrderByDescending(ds => ds.LastWriteTimeUtc).First(); 

    try 
    { 
     foreach (FileInfo file in d.GetFiles()) 
     { 
      string plaintext = ""; 
      string filename = file.Name; 
      byte[] cipherText = new byte[file.Length]; 
      FileStream fs = file.OpenRead(); 
      fs.Read(cipherText, 0, (int)file.Length); 
      byte[] keybytes = Encoding.UTF8.GetBytes("7061737323313233"); 
      byte[] iv = Encoding.UTF8.GetBytes("7061737323313233"); 
      MyWebService.MyWebServicedts = new MyWebService.MyWebService(); 
      using (var rijAlg = new RijndaelManaged()) 
      { 
       rijAlg.Mode = CipherMode.CBC; 
       rijAlg.Padding = PaddingMode.PKCS7; 
       rijAlg.FeedbackSize = 128; 

       rijAlg.Key = keybytes; 
       rijAlg.IV = iv; 
       var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV); 
       using (var msDecrypt = new MemoryStream(cipherText)) 
       { 
        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
        { 
         using (var srDecrypt = new StreamReader(csDecrypt)) 
         { 
          plaintext = srDecrypt.ReadToEnd(); 
         } 
        } 
       } 
      } 
      plaintext = plaintext.Substring(23); 
      string name = filename.Substring(filename.LastIndexOf("/") + 1); 
      name = name.Replace(".encrypted", ""); 
      dts.FileUpload(folderPath, plaintext, name); 
     } 
    } 
    catch (Exception ex) 
    { 
     string err = ex.Message; 
    } 
} 

サーバー上のファイルとしてデータを保存するためのWebサービス:

byte[] byteUploadFile = Convert.FromBase64String(uploadData); 
BinaryWriter binWriter = new   BinaryWriter(File.Open(Path.Combine(folderPath, fileName), FileMode.Create, FileAccess.ReadWrite)); 
binWriter.Write(byteUploadFile); 
binWriter.Close(); 
0

ファイルへの出力を書き込むように見えるJavaScriptからwindow.btoa(ct1)、w hichはBase64でエンコードされています。 C#ではバイナリデータとしてファイルの内容を読み込みます。

簡単に読み取ること:

string base64 = File.ReadAllText(strInputFile); 
byte[] decoded = Convert.FromBase64String(base64); 

using (Aes aes = Aes.Create()) 
using (ICryptoTransform decryptor = aes.CreateDecryptor(bytKey, bytIV)) 
using (var fsOutput = File.Create(strOutputFile)) 
using (var cryptoStream = new CryptoStream(fsOutput, decryptor, CryptoStreamMode.Write)) 
{ 
    cryptoStream.Write(decoded, 0, decoded.Length); 
} 

(特に大規模なデータのための)より良い性能を:

using (var fsInput = File.OpenRead(strInputFile)) 
using (var fsOutput = File.Create(strOutputFile)) 
using (Aes aes = Aes.Create()) 
using (ICryptoTransform decryptor = aes.CreateDecryptor(bytKey, bytIV)) 
using (var decryptionStream = new CryptoStream(fsOutput, decryptor, CryptoStreamMode.Write)) 
using (var base64Decode = new FromBase64Transform()) 
using (var cryptoStream = new CryptoStream(decryptionStream, base64Decode, CryptoStreamMode.Write)) 
{ 
    fsInput.CopyTo(cryptoStream); 
} 

第2の例では、データフローである:そして

fsInput.CopyTo(cryptoStream) -> 
    read some data from fsInput 
    write data to cryptoStream 
     Base64Decode the data in progress 
     write decoded data to decryptionStream 
      decrypt the data in progress 
       write decrypted to fsOutput 
    loop until reading says it's out of data. 

オン}(逆順で全員に電話をかける)

次のように解決された
cryptoStream.Dispose() -> cryptoStream.FlushFinalBlock() -> 
    base64Decode will throw if there's bad data remaining 
decryptionStream.Dispose() -> decryptionStream.FlushFinalBlock() -> 
    throw if padding is bad, otherwise write the final block to fsOutput 
+0

あなたの提案ごとにコードを追加しました。元の質問の 'DecryptFile()'を参照してください。 **パディングが無効で、削除できません**エラーが発生しました。 – Noob

+0

また、サーバー上にファイルを作成/保存するために使用しているWebサービスのmehtodを追加しました。ファイルに書き込むときにBsae64がバイナリに変換されているように見えます。 – Noob

+0

私はこの 'aes.Padding = PaddingMode.Zeros;'も追加しました。今、エラーはなくなりました。ただし、復号化されたファイルは元のファイルと同じではありません。元のファイル:4KB、ecnrypted:7KB、解読:5KB – Noob

関連する問題