J'ai un cryptage de fichier côté client en javascript en utilisant CryptoJs. J'ai un déchiffrement de fichier côté serveur à l'aide de RijndaelManaged. Si je fais à la fois le cryptage et le décryptage à l'aide de CryptoJs, cela fonctionne bien. Cependant, lorsque j'essaie de déchiffrer à l'aide du code C #, cela génère l'erreur ci-dessous. J'ai essayé de régler différents rembourrages, modes, etc. en vain.

CryptographicException length of the data to decrypt is invalid

Code 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);
})
}

Décryptage à l'aide de 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;
}

Méthode 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
Noob 17 janv. 2017 à 19:32

2 réponses

Meilleure réponse

Résolu comme ci-dessous:

Chiffrement de fichiers à l'aide de CryptoJS:

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);
}

Décryptage à l'aide de C #:

  [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;
    }
}

Webservice pour enregistrer les données sous forme de fichier sur le serveur:

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
Noob 3 févr. 2017 à 21:24

Depuis javascript, vous semblez écrire dans le fichier la sortie de window.btoa(ct1), qui est encodée en Base64. En C #, vous lisez le contenu du fichier sous forme de données binaires.

Facile à lire:

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);
}

Meilleures performances (en particulier pour les données volumineuses):

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);
}

Dans le deuxième exemple, le flux de données est:

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.

Puis sur le } (appelez Dispose sur tout le monde dans l'ordre inverse)

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
bartonjs 17 janv. 2017 à 16:59