Входные данные не полный блок - PullRequest
0 голосов
/ 06 декабря 2011

enter image description hereenter image description here Сценарий: один симметричный ключ, у каждого пользователя есть свой IV, документы хранятся в поле NVARCHAR (MAX). Когда я пытаюсь расшифровать файл, я получаю:
Входные данные не являются полным блоком.

// Create symmetric key
public static byte[] CreateKey()
{
    AesCryptoServiceProvider aesCrypto = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
    byte[] key = aesCrypto.Key;
    return key;
}

//Get key (stored in a database)
public static Byte[] GetAppKey()
{
    return db.Encryptors.Where(x => x.EncryptorID == 1).Single().EncryptionKey.ToArray();
}

// Get application IV (stored in database)
public static Byte[] GetAppIV()
{
    return db.Encryptors.Where(x => x.EncryptorID == 1).Single().IV.ToArray();
}

// Encrypt document (this will be stored in a VARBINARY(MAX) field
public static byte[] EncryptBinaryToBytes(Binary document, byte[] iv)
{
    byte[] key = GetAppKey();
    byte[] encrypted;

    using (AesCryptoServiceProvider aesCsp = new AesCryptoServiceProvider())
    {
        aesCsp.Key = key;
        aesCsp.IV = iv;

        ICryptoTransform encryptor = aesCsp.CreateEncryptor(aesCsp.Key, aesCsp.IV);

        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(document);
                }
                encrypted = msEncrypt.ToArray();
            }
        }
    }
    // return the encrypted document
    return encrypted;
}

// Decrypt document
public static byte[] DecryptBytesToBytes(byte[] document, byte[] iv) 
{
    byte[] key = GetAppKey();

    using (AesCryptoServiceProvider aesCsp = new AesCryptoServiceProvider())
    {
        aesCsp.Key = key;
        aesCsp.IV = iv;

        ICryptoTransform decryptor = aesCsp.CreateDecryptor(aesCsp.Key, aesCsp.IV);

        using (MemoryStream msDecrypt = new MemoryStream())
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swDecrypt = new StreamWriter(csDecrypt))
                {
                    swDecrypt.Write(document);
                }
                byte[] decrypted = msDecrypt.ToArray();
                // return the unencrypted document
                return decrypted;
            }
        }
    }
}

Заранее спасибо.

Для хранения документа

    byte[] fileByte = fluUploadFile.FileBytes;
    Binary document = new Binary(fileByte);

    byte[] appIv = AES.GetAppIV();
    byte[] encryptedDocument = AES.EncryptBinaryToBytes(document, appIv);
    byte[] decryptedDocument = AES.DecryptBytesToBytes(encryptedDocument, appIv);
    Document d = new Document()
    {
        OriginalName = originalName,
        DocSize = fileSize,
        BinaryDocument = encryptedDocument,
        UploadedName = uploadedFileName,
        MimeType = MIMEType,
        DocExtension = extension
    };
    db.Documents.InsertOnSubmit(d);
    db.SubmitChanges();

1 Ответ

2 голосов
/ 06 декабря 2011

Очень важно, чтобы вы изменили тип данных поля базы данных на VARBINARY(MAX), чтобы избежать проблем с кодировкой символов и комбинациями байтов, которые нельзя интерпретировать как допустимые символы.

Кроме того, я думаю, что проблема в том, что вы не закрываете потоки перед вызовом метода ToArray() для MemoryStream в процедурах шифрования и дешифрования. Очень важно вызвать Close() в CryptoStream, чтобы был вызван FlushFinalBlock() и процесс шифрования записал последний поток в поток.

Попробуйте переместить вызов на MemoryStream.ToArray() во внешний блок using, то есть за пределами блока using в CryptoStream, чтобы Dispose() вызывался на CryptoStream и вызывался MemoryStream.Close() до этого.

Другая проблема с вашим кодом заключается в том, что вы оборачиваете CryptoStream в StreamWriter, который записывает text представление объекта, который вы передаете, в метод Write. Вместо этого вам следует писать прямо в CryptoStream, чтобы избежать преобразования байтов в строки.

...