我對C#很陌生,所以請原諒我這個。我一直用這個長長的時間撞着我的頭靠在牆上,我找不到解決方案。可能它非常明顯。爲什麼我不能單獨使用加密和文件存儲?
所以這裏是:我正在寫一些對象屬性到一個文件。首先我將屬性轉換爲字節數組,然後將整個數組(一個對象)放在一起,並使用Aes通過MemoryStream對其進行加密。我知道序列化和其他可能性,但我真的需要這樣做。在其他一些方法中,我以塊(「對象」)讀取該文件,對其進行解密,然後從字節數組中重建對象屬性。事情是,只有第一個記錄(「對象」)被正確/正確地解密和重構。所有其他人都搞亂了數據(int獲取值48464而不是2,String顯示奇數符號,double是-3.16 ... E-161而不是20 ...)。
我不知道爲什麼。我嘗試了我可能想到的一切。如果我將加密和解密註釋掉一切正常,那麼寫入&就不會出現問題。如果我將解碼和重構對象的代碼放在加密代碼的下面(以便解密寫入的數據塊),它將對所有內容進行解密和重構,因此解密和重構不應該成爲問題。但當它們在一起時,它就會變得混亂起來。我真的迷失在這裏。
請不要關注我操縱數據的方式,現在它真的不重要,我有我的理由爲什麼我這樣做。
這裏是保存到文件的整個代碼:
//constant for setting inUse
byte setInUse = 0x80; //1000 0000
//constant for adding spaces to name (string)
byte[] space = Encoding.UTF8.GetBytes(" ");
//result
byte[] data = new byte[32];
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
aes.Padding = PaddingMode.None;
ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);
//setup file stream for saving data
FileStream fStream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false);
if(writeIndex != 0)
fStream.Position = writeIndex +1;
fStream.Position = 0; //delete me
foreach(Article article in articles)
{
if(article.MyIsNew)
{
article.MyInUseChanged = false;
article.MyPriceChanged = false;
//convert article to byte array
//id
byte[] id = BitConverter.GetBytes(Convert.ToUInt16(article.MyId));
//in use
if (article.MyInUse)
id[0] = (byte)(id[0] | setInUse);
data[0] = id[0];
data[1] = id[1];
//stock
byte[] stock = BitConverter.GetBytes(article.MyStock);
data[2] = stock[0];
data[3] = stock[1];
data[4] = stock[2];
data[5] = stock[3];
data[6] = stock[4];
data[7] = stock[5];
data[8] = stock[6];
data[9] = stock[7];
//name
byte[] name = Encoding.UTF8.GetBytes(article.MyName);
int counter = 10;
for (int i = 0; i < name.Length; i++)
{
data[counter] = name[i];
counter++;
}
//adding spaces
int numToAdd = 22-name.Length;
for (int i = 0; i < numToAdd; i++)
{
data[counter] = space[0];
}
//encrypt
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write))
c.Write(data, 0, data.Length);
byte[] original = new byte[32];
original = m.ToArray();
fStream.Write(original, 0, original.Length);
}
else if (article.MyInUseChanged)
{
}
if (article.MyPriceChanged)
{
}
}
fStream.Flush();
fStream.Close();
fStream.Dispose();
這裏是加載整個代碼:
String fileName = path + "\\articles";
//load data
if (File.Exists(fileName))
{
FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
aes.Padding = PaddingMode.None;
ICryptoTransform decryptor = aes.CreateDecryptor(key, iv);
//constant for extracting inUse
byte inUseConst = 0x80;
//constant for extracting id
byte idConst = 0x7F;
byte[] idArray = new byte[2];
//reading & constructing & adding articles to the list
int numBytesToRead = (int)fStream.Length;
while (numBytesToRead > 0)
{
byte[] original = new byte[32];
byte[] data = new byte[32];
int len = fStream.Read(original, 0, 32);
numBytesToRead -= 32;
if (len == 0 || len != 32)
{
MessageBox.Show("Error while loading articles");
break;
}
long pos = fStream.Position; //delete me
//decrypt
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write))
c.Write(original, 0, original.Length);
data = m.ToArray();
//constructing object - article
//inUse
byte inUseCalc = (byte)(data[0] & inUseConst);
bool inUse = false;
if (inUseCalc != 0)
{
inUse = true;
}
//id
data[0] = (byte)(data[0] & idConst);
int id = (int)(BitConverter.ToUInt16(data, 0));
//stock
double stock = BitConverter.ToDouble(data, 2);
//name
String name = Encoding.UTF8.GetString(data, 10, 22);
Article article = new Article(id, 10, name, inUse, stock);
articles.Add(article);
有些東西是不是最佳的,因爲我改變了很多剛嘗試找到解決方案。有些東西(比如轉換爲uInt16並使用「或」等)部分原因是壓縮。
請幫我解決這個問題,請不要關注我對數據的處理或者建議我使用序列化或二進制編寫器或類似的東西,我真的有我的理由。
我真的相信你,因爲我完全沒有想法。謝謝大家寶貴的時間和答案。
你可能要考慮現在更換你的鑰匙... – 2011-02-22 23:55:56
@Greg Buehler這是我用過的硬鑰匙,直到我得到所有其他工作。當然我會改變它,它絕對不會被硬編碼。 – Ben 2011-02-23 08:41:09