博主最近在做資料庫加密專案,專案中需要實現資料庫中資料密文與金鑰異地儲存,其功能已實現,但考慮到金鑰在傳輸過程中雖然已經做了加密處理,但是第三方如果惡意替換資料報的話,還是會有安全隱患,應此需要保證二端傳輸接受到的資料一致性。
單向雜湊函式
單向雜湊函式指的是有乙個輸入和乙個輸出的函式,其中輸入的資料成為訊息,輸出稱為雜湊值(hash value)。單向雜湊函式根據訊息內容計算出雜湊值,使用者根據雜湊值保證資料的一致性。乙份合格的單向雜湊函式須具備以下性質
1:輸入的資料可以是任意長度的,輸出的雜湊值最好為固定長度。
2:其演算法複雜度優異,能夠快速計算出雜湊值,不然博主的專案效能又得不合格。
3:需要具備強抗碰撞性,即要找到雜湊值相同的二條不同的訊息是非常困難的。
4:需要具備單向性,即無法通過雜湊值推算出訊息。
在使用單雜湊函式時,需要注意的是。訊息傳輸的過程可以存在被篡改的風險,但是雜湊值的傳輸必須是安全的。
下面我列舉幾個目前未被攻破的單向雜湊函式:
05年sha-1已被攻破,但nist發布的sha-224、sha-256、sha-384,和sha-512(統稱sha-2),截至18年還是安全的。
下面列舉sha-256函式的使用:
sha-256 演算法輸入訊息的最大長度不超過264位元(基本滿足應用)。輸出的雜湊值為256位元。
#include #include #define sha256_rotl(a,b) (((a>>(32-b))&(0x7fffffff>>(31-b)))|(a<>b)&(0x7fffffff>>(b-1)))
#define sha256_ch(x,y,z) ((x&y)^((~x)&z))
#define sha256_maj(x,y,z) ((x&y)^(x&z)^(y&z))
#define sha256_e0(x) (sha256_rotl(x,30)^sha256_rotl(x,19)^sha256_rotl(x,10))
#define sha256_e1(x) (sha256_rotl(x,26)^sha256_rotl(x,21)^sha256_rotl(x,7))
#define sha256_o0(x) (sha256_rotl(x,25)^sha256_rotl(x,14)^sha256_sr(x,3))
#define sha256_o1(x) (sha256_rotl(x,15)^sha256_rotl(x,13)^sha256_sr(x,10))
extern char* strsha256(const char* str, long long length, char* sha256);
l = length + ((length % 64 > 56) ? (128 - length % 64) : (64 - length % 64));
if (!(pp = (char*)malloc((unsigned long)l))) return 0;
for (i = 0; i < length; pp[i + 3 - 22 * (i % 4)] = str[i], i++);
for (pp[i + 3 - 22 * (i % 4)] = 128, i++; i < l; pp[i + 3 - 22 * (i % 4)] = 0, i++);
*((long*)(pp + l - 4)) = length << 3;
*((long*)(pp + l - 8)) = length >> 29;
for (ppend = pp + l; pp < ppend; pp += 64)
h0 += a, h1 += b, h2 += c, h3 += d, h4 += e, h5 += f, h6 += g, h7 += h;
} free(pp - l);
sprintf(sha256, "%08x%08x%08x%08x%08x%08x%08x%08x", h0, h1, h2, h3, h4, h5, h6, h7);
return sha256;
} extern char* filesha256(const char* file, char* sha256);
fh = fopen(file, "rb");
fseek(fh, 0, seek_end);
length = _ftelli64(fh);
addlsize = (56 - length % 64 > 0) ? (64) : (128);
if (!(addlp = (char*)malloc(addlsize))) return 0;
cpys = ((length - (56 - length % 64)) > 0) ? (length - length % 64) : (0);
j = (long)(length - cpys);
if (!(pp = (char*)malloc(j))) return 0;
fseek(fh, -j, seek_end);
fread(pp, 1, j, fh);
for (i = 0; i < j; addlp[i + 3 - 22 * (i % 4)] = ((char*)pp)[i], i++);
free(pp);
for (addlp[i + 3 - 22 * (i % 4)] = 128, i++; i < addlsize; addlp[i + 3 - 22 * (i % 4)] = 0, i++);
*((long*)(addlp + addlsize - 4)) = length << 3;
*((long*)(addlp + addlsize - 8)) = length >> 29;
for (rewind(fh); 64 == fread(w, 1, 64, fh);)
h0 += a, h1 += b, h2 += c, h3 += d, h4 += e, h5 += f, h6 += g, h7 += h;
} for (pp = addlp, ppend = addlp + addlsize; pp < ppend; (long*)pp += 16)
h0 += a, h1 += b, h2 += c, h3 += d, h4 += e, h5 += f, h6 += g, h7 += h;
} free(addlp); fclose(fh);
sprintf(sha256, "%08x%08x%08x%08x%08x%08x%08x%08x", h0, h1, h2, h3, h4, h5, h6, h7);
return sha256;
}
回到開頭的問題,博主的專案的安全問題便有了解決方案。假設alice端需要給bob端傳送一組金鑰,alice將金鑰的雜湊值算出然後附在傳送包裡,通過alice和bob之間的共享金鑰進行xor加密後傳送。bob收到資料後通過共享金鑰解密,然後比較雜湊值與金鑰是否一致。由於第三方不可能獲取到共享金鑰,改動傳送包裡的資料,bob端就能立馬知曉。 資料一致性
資料一致性通常指關聯資料之間的邏輯關係是否正確和完整。而資料儲存的一致性模型則可以認為是儲存系統和資料使用者之間的一種約定。如果使用者遵循這種約定,則可以得到系統所承諾的訪問結果。常用的一致性模型有 a 嚴格一致性 linearizability,strict atomic consistency ...
資料一致性
丟失更新 未確定的相關性 不一致的分析和幻想讀 事務a讀取與搜尋條件相匹配的若干行。事務b以插入或刪除行等方式來修改事務a的結果集,然後再提交。幻讀是指當事務不是獨立執行時發生的一種現象,例如第乙個事務對乙個表中的資料進行了修改,比如這種修改涉及到表中的 全部資料行 同時,第二個事務也修改這個表中的...
資料一致性
資料一致性通常指關聯資料之間的邏輯關係是否正確和完整。而資料儲存的一致性模型則可以認為是儲存系統和資料使用者之間的一種約定。如果使用者遵循這種約定,則可以得到系統所承諾的訪問結果。常用的一致性模型有 a 嚴格一致性 linearizability,strict atomic consistency ...