Sql-Server
如何解密 MSSQL 表中的壓縮數據
我們正在嘗試從其他人的 MS SQL 數據庫導入(逆向工程)一些數據,而沒有任何供應商支持。
過去,數據以純文字或 RTF 格式儲存,因此很容易提取。但是這個數據庫有一些看起來“加密”的內容。如果數據採用這種格式,則還有另一列“zipped”= 1。我被告知他們正在壓縮數據以保持在 SQL Express 的 10GB 限制之下。
它看起來有點像這樣:
-Ëj„@D÷ þC}€7!2‹<Pɾí¾êÍôCn·ÿ~¦6UÅ©–F
關於如何解碼的任何想法?同一個表中還有其他行是純文字或 RTF,但很多都是這種格式。
這是數據庫的範例導出:
https://1drv.ms/u/s!Au6oldAhXo2M5Xt_bE9Q5iA0WdfF?e=IsuYdQ
其中包括它應該是什麼樣子的螢幕截圖。
數據未加密;它只是使用Deflate壓縮的,這在 TSQL 中不直接可用。TSQL COMPRESS使用 Gzip,它是類似的,但不嚴格兼容。所以在 C# 中是這樣的:
using System.Data.SqlClient; using System.IO; using System.IO.Compression; using var con = new SqlConnection("server=.;database=spmcopy;integrated security=true;multipleactiveresultsets=true"); con.Open(); var cmd = new SqlCommand("select counter, cast(cast([text] as varchar(max)) as varbinary(max)) ZippedText from notescopy where Zipped=1 ", con); var cmdWrite = new SqlCommand("update notescopy set [text] = cast(cast(@t as varchar(max)) as text), Zipped = 0 where counter = @c",con); var ptext = cmdWrite.Parameters.Add(new SqlParameter("@t", System.Data.SqlDbType.VarBinary, -1)); var pCounter = cmdWrite.Parameters.Add(new SqlParameter("@c", System.Data.SqlDbType.Int)); using var reader = cmd.ExecuteReader(); while (reader.Read()) { pCounter.Value = reader.GetInt32(0); var compressedStream = reader.GetStream(1); var dest = new MemoryStream(); var decompressedStream = new DeflateStream(compressedStream, CompressionMode.Decompress); decompressedStream.CopyTo(dest); dest.Position = 0; ptext.Value = dest.ToArray(); cmdWrite.ExecuteNonQuery(); }
此外,看起來您可以在 Deflate 流中添加一個標準的 10 字節標頭以使其與 GZip 兼容,所以
select cast(decompress(cast(0x1F8B0800000000000400 as varbinary(max)) + cast(cast([text] as varchar(max)) as varbinary(max))) as varchar(max)) d from notescopy
看起來 DECOMPRESS 會忽略 CRC32 和 ISIZE 尾欄位(如果它們不存在),這是合規的,但不是強制性的解壓縮器行為。