sha1 演算法:
訊息摘要演算法,把訊息按照512 bits進行分組,不斷的對5個int型變數進行計算,直到所有訊息都運算完畢。
最終得到 160 bit 即 20 位元組的雜湊值。流程圖:
c語言實現:
用到的資料結構:
//sha1演算法的上下文,儲存一些狀態,中間資料,結果
typedef struct sha1_ctx
sha1_ctx;
具體流程:
1.
一開始呼叫sha1_init初始化 5 個 int 型變數摘要(這是演算法的特徵,peid的演算法識別外掛程式會識別):
//內部函式,sha1演算法的上下文的初始化
static void zen_sha1_init(sha1_ctx *ctx)
2.接著就是把訊息按照 512 bits 進行分組,輪流進行sha1_update,不斷更新這 5個int型變數,
直到所有訊息都參與了 sha1_update 計算。
sha1_update內部呼叫sha1_process_block把64位元組的訊息分成 16 個 int型變數,並把這 16 個變數通過
64 次迴圈 擴充套件到80 個 int 型變數。再通過80次迴圈,分別用 迴圈移位,加法運算,異或運算, 把初始化好的
雜湊值與訊息進行雜湊處理。最後再加回原來的雜湊值,得到 sha1_update 後的 雜湊值。
/*!
@brief 內部函式,對乙個64bit記憶體塊進行摘要(雜湊)處理,
@param hash 存放計算hash結果的的陣列
@param block 要計算的處理得記憶體塊
*/static void zen_sha1_process_block(uint32_t hash[5],
const uint32_t block[zen_sha1_block_size / 4])
a = hash[0];
b = hash[1];
c = hash[2];
d = hash[3];
e = hash[4];
for (t = 0; t < 20; t++)
for (t = 20; t < 40; t++)
for (t = 40; t < 60; t++)
for (t = 60; t < 80; t++)
hash[0] += a;
hash[1] += b;
hash[2] += c;
hash[3] += d;
hash[4] += e;
}
3.補充: 最後乙個訊息塊不足 512 bit
要進行擴充套件處理,用0 填充,並且最後 64 位用於存放整個訊息的長度,然後
呼叫sha1_update更新雜湊值。
/*!
@brief 內部函式,處理資料的最後部分,新增0x80,補0,增加長度資訊
@param ctx 演算法的上下文,記錄中間資料,結果等
@param msg 要進行計算的資料buffer
@param result 返回的結果
*/static void zen_sha1_final(sha1_ctx *ctx,
const unsigned char *msg,
size_t size,
unsigned char *result)
//得到0x80要新增在的位置(在uint32_t 陣列中),
uint32_t index = ((uint32_t)ctx->length_ & 63) >> 2;
uint32_t shift = ((uint32_t)ctx->length_ & 3) * 8;
//新增0x80進去,並且把餘下的空間補充0
message[index] &= ~(0xffffffff << shift);
message[index++] ^= 0x80 << shift;
//如果這個block還無法處理,其後面的長度無法容納長度64bit,那麼先處理這個block
if (index > 14)
zen_sha1_process_block(ctx->hash_, message);
index = 0;
}//補0
while (index < 14)
//儲存長度,注意是bit位的長度,這個問題讓我看著鬱悶了半天,
uint64_t data_len = (ctx->length_) << 3;
//注意sha1演算法要求的64bit的長度是大頭big-endian,在小頭的世界要進行轉換
#if zen_bytes_order == zen_little_endian
data_len = zen_swap_uint64(data_len);
#endif
message[14] = (uint32_t) (data_len & 0x00000000ffffffff);
message[15] = (uint32_t) ((data_len & 0xffffffff00000000ull) >> 32);
zen_sha1_process_block(ctx->hash_, message);
//注意結果是大頭黨的,在小頭的世界要進行轉換
#if zen_bytes_order == zen_little_endian
swap_uint32_memcpy(result, &ctx->hash_, zen_sha1_hash_size);
#else
memcpy(result, &ctx->hash_, zen_sha1_hash_size);
#endif
}
4.附上使用的方法:
//每次處理的block的大小
static const size_t zen_sha1_block_size = 64;
/*!@brief 內部函式,處理資料的前面部分(>64位元組的部分),每次組成乙個64位元組的block就進行雜湊處理
@param ctx 演算法的上下文,記錄中間資料,結果等
@param msg 要進行計算的資料buffer
@param size 長度
*/static void zen_sha1_update(sha1_ctx *ctx,
const unsigned char *buf,
size_t size)
ctx->unprocessed_ = size;
}//計算乙個記憶體資料的sha1值
unsigned char *sha1(const unsigned char *msg,
size_t size,
unsigned char result[zen_sha1_hash_size])
// main 函式進行sha1 的使用:
int main()
{ unsigned char buf="hunter";
unsigned char result[zen_sha1_hash_size];
sha1(buf,6,result);
for(int i=0;i參考:
《**密碼技術:結城浩》
**出自:未知,不是本人寫的。
SHA 1摘要演算法原始碼
public class sha1 摘要資料儲存陣列 private int digestint new int 5 計算過程中的臨時資料儲存陣列 private int tmpdata new int 80 計算sha 1摘要 private int process input bytes byt...
SHA1演算法原理
1 sha1演算法簡介 安全雜湊演算法 secure hash algorithm 主要適用於數字簽名標準 digital signature standard dss 裡面定義的數字簽名演算法 digital signature algorithm dsa 對於長度小於2 64位的訊息,sha1會...
Sha 1演算法詳解
一 hash函式和訊息完整性 二 常見的hash函式 三 sha 1演算法實現的基本步驟 1 將訊息摘要轉換成位字串 01100001 01100010 01100011 2 對轉換後的位字串進行補位操作 初始的資訊摘要 01100001 01100010 01100011 第一步補位 011000...