#include "Salt_SHA512_PBKDF2.h"
#download from pudn
// 旋转操作
inline u rrot(u val, int pos) {
pos %= 64;
return ( val >> pos ) | ( val << (64 - pos) );
}
inline u ch(u x, u y, u z) {
return (x & y) ^ ((~x) & z);
}
inline u maj(u x, u y, u z) {
return (x & y) ^ (x & z) ^ (y & z);
}
inline u sigma0(u x) {
return rrot( x,28 ) ^ rrot( x,34 ) ^ rrot( x,39 );
}
inline u sigma1(u x) {
return rrot( x,14 ) ^ rrot( x,18 ) ^ rrot( x,41 );
}
inline u sg0(u x) {
return rrot(x,1) ^ rrot(x,8) ^ (x>>7);
}
inline u sg1(u x) {
return rrot(x,19) ^ rrot(x,61) ^ (x>>6);
}
static const u K[80] = {
0x428a2f98d728ae22, 0x7137449123ef65cd,
0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
0x3956c25bf348b538, 0x59f111f1b605d019,
0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
0xd807aa98a3030242, 0x12835b0145706fbe,
0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
0x72be5d74f27b896f, 0x80deb1fe3b1696b1,
0x9bdc06a725c71235, 0xc19bf174cf692694,
0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
0x2de92c6f592b0275, 0x4a7484aa6ea6e483,
0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
0x983e5152ee66dfab, 0xa831c66d2db43210,
0xb00327c898fb213f, 0xbf597fc7beef0ee4,
0xc6e00bf33da88fc2, 0xd5a79147930aa725,
0x06ca6351e003826f, 0x142929670a0e6e70,
0x27b70a8546d22ffc, 0x2e1b21385c26c926,
0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
0x650a73548baf63de, 0x766a0abb3c77b2a8,
0x81c2c92e47edaee6, 0x92722c851482353b,
0xa2bfe8a14cf10364, 0xa81a664bbc423001,
0xc24b8b70d0f89791, 0xc76c51a30654be30,
0xd192e819d6ef5218, 0xd69906245565a910,
0xf40e35855771202a, 0x106aa07032bbd1b8,
0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
0x748f82ee5defb2fc, 0x78a5636f43172f60,
0x84c87814a1f0ab72, 0x8cc702081a6439ec,
0x90befffa23631e28, 0xa4506cebde82bde9,
0xbef9a3f7b2c67915, 0xc67178f2e372532b,
0xca273eceea26619c, 0xd186b8c721c0c207,
0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
0x06f067aa72176fba, 0x0a637dc5a2c898a6,
0x113f9804bef90dae, 0x1b710b35131c471b,
0x28db77f523047d84, 0x32caab7b40c72493,
0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
0x5fcb6fab3ad6faec, 0x6c44198c4a475817
};
///////////////////////////////////////////////
//
// 函数名称: HMAC
// 函数功能: HMAC算法,主要配合上SHA512计算哈希值
// 函数参数: lpInSlatBuf: 盐值
// 函数参数: nSaltSize: 盐的大小
// 函数参数: lpInPasswd: 测试的密码值
// 函数参数: nPasswdSize: 密码大小
// 函数返回值: TRUE 表示成功 FALSE则失败
//
//////////////////////////////////////////////
BOOL HMAC(char *lpInSlatBuf, int nSaltSize, char *lpInPasswd, int nPasswdSize, char *lpOutBuf, int nOutBufSize)
{
byte c;
byte *tmpBuf = NULL;
u H[8] = {0};
u Key[16] = {0};
u X[16] = {0};
u Y[16] = {0};
u ipad = 0x3636363636363636;
u opad = 0x5c5c5c5c5c5c5c5c;
int k;
tmpBuf = (byte*)malloc(nSaltSize + sizeof(X) * 2);
memset(tmpBuf,0,nSaltSize + sizeof(X) * 2);
//Process string key into sub-key
//Hash key in case it is less than 64 bytes
if (nPasswdSize > 64)
{
sha_512(lpInPasswd, nPasswdSize, (char*)H,sizeof(H));
Key[0] = H[0];
Key[1] = H[1];
Key[2] = H[2];
Key[3] = H[3];
Key[4] = H[4];
Key[5] = H[5];
Key[6] = H[6];
Key[7] = H[7];
}
else
{
for(int i=0; i<16; i++)
{
for(int j=0; j<8; j++)
{
if (8*i+j <= nPasswdSize)
{
k = lpInPasswd[8*i+j];
}
else
{
k = 0;
}
if (k<0)
{
k = k + 256;
}
Key[i]= Key[i] + u(k*pow(256,7-j));
}
}
}
for(int i=0; i<16; i++)
{
X[i] = Key[i]^ipad;
Y[i] = Key[i]^opad;
}
//Turn X-Array into a String
for(i=0; i<16; i++)
{
for(int j=0; j<8; j++)
{
c = ((X[i] >> 8*(7-j)) % 256);
tmpBuf[i * 8 + j] = c;
}
}
//Append text to string
//s = s + text;
memcpy(tmpBuf + sizeof(X),lpInSlatBuf,nSaltSize);
//Hash X-Array
sha_512((const char*)tmpBuf,sizeof(X) + nSaltSize, (char*)H, sizeof(H));
// s = "";
memset(tmpBuf,0,nSaltSize + 0x80 * 2);
//Turn Y-Array into a String
for(i=0; i<16; i++)
{
for(int j=0; j<8; j++)
{
c = ((Y[i] >> 8*(7-j)) % 256);
tmpBuf[i * 8 + j] = c;
}
}
//Append Hashed X-Array to Y-Array in string
for(i=0; i<8; i++)
{
for(int j=0; j<8; j++)
{
c = ((H[i] >> 8*(7-j)) % 256);
tmpBuf[0x80 + i * 8 + j] = c;
}
}
//Hash final concatenated string
sha_512((const char*)tmpBuf, 0xC0, (char*)H, sizeof(H));
if(nOutBufSize >= sizeof(H))
{
memcpy(lpOutBuf,H,sizeof(H));
free(tmpBuf);
return TRUE;
}
free(tmpBuf);
return FALSE;
}
///////////////////////////////////////////////
//
// 函数名称: sha_512
// 函数功能: sha_512哈希算法
// 函数参数: lpInBuf: 输入数据缓冲区
// 函数参数: nInBufSize: 输入缓冲区大小
// 函数参数: lpOutBuf: 输出数据缓冲区
// 函数参数: nOutBufSize: 输出缓冲区大小
// 函数返回值: TRUE 表示成功 FALSE则失败
//////////////////////////////////////////////
BOOL sha_512(const char* lpInBuf, int nInBufSize, char *lpOutBuf, int nOutBufSize)
{
u w[80];
u H[8] = {0};
uint orilen = nInBufSize;
uint chunks_count = (orilen+17)/128;
if( (orilen+17)%128!=0 ) ++chunks_count;
u total_count = orilen * 8;
u *fidata = (u*)malloc(sizeof(u) * chunks_count*16);
memset(fidata, 0, sizeof(u)*chunks_count*16);
ubyte *pdata = (ubyte *)fidata;
uint idx;
for (idx = 0; idx < orilen; ++idx) //关键是这里的复制
{
pdata[idx+7-idx%8-idx%8] = (ubyte)lpInBuf[idx];
}
pdata[idx+7-idx%8-idx%8] = 0x80;
++idx;
// 警告,实际上只用了64位记录长度,没用到规定的的128位
// 因为程序只供学习,所以不必要做得很完善
ubyte *pbyte = (ubyte *)&total_count;
uint i = 0;
uint j = 0;
int kki = 0;
for (i = 0, j = 128*chunks_count - 4; i < 8; ++i) {
if (i==4) j -= 8;
pdata[j + i] = pbyte[i];
}
pbyte = ((ubyte *)fidata) + (128*chunks_count - 8);
*((u *)(pbyte)) = total_count;
H[0] = 0x6a09e667f3bcc908;
H[1] = 0xbb67ae8584caa73b;
H[2] = 0x3c6ef372fe94f82b;
H[3] = 0xa54ff53a5f1d36f1;
H[4] = 0x510e527fade682d1;
H[5] = 0x9b05688c2b3e6c1f;
H[6] = 0x1f83d9abfb41bd6b;
H[7] = 0x5be0cd19137e2179;
for (i = 0; i < chunks_count*16; i += 16)
{
u *puint = &fidata[i]; //puint = 888那个地址
uint j = 0;
for (j = 0; j < 16; ++j) {
w[j] = puint[j];
}
for (j = 16; j < 80; ++j) {
w[j] = sg1(w[j-2]) + w[j - 7] + sg0(w[j-15]) + w[j - 16];
}
u a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7];
for (j = 0; j < 80; ++j) {
u t1 = h + sigma1(e) + ch(e,f,g) + K[j] + w[j];
u t2 = sigma0(a) + maj(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
H[0] += a, H[1] += b, H[2] += c, H[3] += d, H[4] += e, H[5] += f, H[6] += g, H[7] += h;
}
if(nOutBufSize >= 0x40)
{
memcpy(lpOutBuf,H,sizeof(H));
free(fidata);
return TRUE;
}
free(fidata);
return FALSE;
}
///////////////////////////////////////////////
//
// 函数名称: PBKDF2
// 函数功能: PBKDF2算法将密码进行多次哈希计算
// 函数参数: lpInSalt: 输入盐值
// 函数参数: nSaltSize: 盐的大小
// 函数参数: lpInPasswd: 输入的密码
// 函数参数: nPasswdSize: 密码大小
// 函数参数: nIterations: 变换次数
// 函数参数: lpOutBuf: 输出缓冲区
// 函数参数: dkLen: 要输出多少个字节,
// 函数返回值: TRUE 表示成功 FALSE则失败
// 注意:最后一个参数dkLen 这个值是哈希算法的倍数,这里我们计算的苹果的密码所以这里应该传0x80
//////////////////////////////////////////////
BOOL PBKDF2(char *lpInSalt, int nSaltSize, char *lpInPasswd, int nPasswdSize,int nIterations, char *lpOutBuf,int dkLen)
{
if((dkLen < 0) || (dkLen % 0x40))
{
return FALSE;
}
int hlen,l;
int i = 0;
char *tmpBuf = (char*)malloc(nSaltSize +
评论0