首页
社区
课程
招聘
SHA-1计算出的摘要怎样转换为一个整数?
发表于: 2010-12-13 13:20 5875

SHA-1计算出的摘要怎样转换为一个整数?

2010-12-13 13:20
5875
SHA-1计算出的Hash值分为五个分块存放,那怎样将它连接转换成一个整数呢???
     麻烦大家帮帮忙哈~谢谢!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
5个块拿来XOR一下。。。。
2010-12-13 16:16
0
雪    币: 157
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
那最终得出的是一个32位的值?
2010-12-14 10:26
0
雪    币: 517
活跃值: (35)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
按字节读取并连接。
2010-12-14 10:49
0
雪    币: 157
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
能具体点么,大数,进行连接,怎么连接我不懂……
2010-12-14 20:10
0
雪    币: 32
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不知道楼主用啥语言写的,一下是一段java代码,可以参考一下最后一段,将数组合并

public class sha1 {
private final int[] abcde = {
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
};

// 摘要数据存储数组
private int[] digestint = new int[5];

// 计算过程中的临时数据存储数组
private int[] tmpdata = new int[80];

// 计算sha-1摘要
private int process_input_bytes(byte[] bytedata) {
// 初试化常量
system.arraycopy(abcde, 0, digestint, 0, abcde.length);

// 格式化输入字节数组,补10及长度数据
byte[] newbyte = bytearrayformatdata(bytedata);

// 获取数据摘要计算的数据单元个数
int mcount = newbyte.length / 64;

// 循环对每个数据单元进行摘要计算
for (int pos = 0; pos < mcount; pos++) {
// 将每个单元的数据转换成16个整型数据,并保存到tmpdata的前16个数组元素中
for (int j = 0; j < 16; j++) {
tmpdata[j] = bytearraytoint(newbyte, (pos * 64) + (j * 4));
}

// 摘要计算函数
encrypt();
}

return 20;
}

// 格式化输入字节数组格式
private byte[] bytearrayformatdata(byte[] bytedata) {
// 补0数量
int zeros = 0;

// 补位后总位数
int size = 0;

// 原始数据长度
int n = bytedata.length;

// 模64后的剩余位数
int m = n % 64;

// 计算添加0的个数以及添加10后的总长度
if (m < 56) {
zeros = 55 - m;
size = n - m + 64;
} else if (m == 56) {
zeros = 63;
size = n + 8 + 64;
} else {
zeros = 63 - m + 56;
size = (n + 64) - m + 64;
}

// 补位后生成的新数组内容
byte[] newbyte = new byte[size];
// 复制数组的前面部分
system.arraycopy(bytedata, 0, newbyte, 0, n);

// 获得数组append数据元素的位置
int l = n;
// 补1操作
newbyte[l++] = (byte) 0x80;

// 补0操作
for (int i = 0; i < zeros; i++) {
newbyte[l++] = (byte) 0x00;
}

// 计算数据长度,补数据长度位共8字节,长整型
long n = (long) n * 8;
byte h8 = (byte) (n & 0xff);
byte h7 = (byte) ((n >> 8) & 0xff);
byte h6 = (byte) ((n >> 16) & 0xff);
byte h5 = (byte) ((n >> 24) & 0xff);
byte h4 = (byte) ((n >> 32) & 0xff);
byte h3 = (byte) ((n >> 40) & 0xff);
byte h2 = (byte) ((n >> 48) & 0xff);
byte h1 = (byte) (n >> 56);
newbyte[l++] = h1;
newbyte[l++] = h2;
newbyte[l++] = h3;
newbyte[l++] = h4;
newbyte[l++] = h5;
newbyte[l++] = h6;
newbyte[l++] = h7;
newbyte[l++] = h8;

return newbyte;
}

private int f1(int x, int y, int z) {
return (x & y) | (~x & z);
}

private int f2(int x, int y, int z) {
return x ^ y ^ z;
}

private int f3(int x, int y, int z) {
return (x & y) | (x & z) | (y & z);
}

private int f4(int x, int y) {
return (x << y) | x >>> (32 - y);
}

// 单元摘要计算函数
private void encrypt() {
for (int i = 16; i <= 79; i++) {
tmpdata[i] = f4(tmpdata[i - 3] ^ tmpdata[i - 8] ^ tmpdata[i - 14] ^
tmpdata[i - 16], 1);
}

int[] tmpabcde = new int[5];

for (int i1 = 0; i1 < tmpabcde.length; i1++) {
tmpabcde[i1] = digestint[i1];
}

for (int j = 0; j <= 19; j++) {
int tmp = f4(tmpabcde[0], 5) +
f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpdata[j] + 0x5a827999;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}

for (int k = 20; k <= 39; k++) {
int tmp = f4(tmpabcde[0], 5) +
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpdata[k] + 0x6ed9eba1;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}

for (int l = 40; l <= 59; l++) {
int tmp = f4(tmpabcde[0], 5) +
f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpdata[l] + 0x8f1bbcdc;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}

for (int m = 60; m <= 79; m++) {
int tmp = f4(tmpabcde[0], 5) +
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpdata[m] + 0xca62c1d6;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}

for (int i2 = 0; i2 < tmpabcde.length; i2++) {
digestint[i2] = digestint[i2] + tmpabcde[i2];
}

for (int n = 0; n < tmpdata.length; n++) {
tmpdata[n] = 0;
}
}

// 4字节数组转换为整数
private int bytearraytoint(byte[] bytedata, int i) {
return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16) |
((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff);
}

// 整数转换为4字节数组
private void inttobytearray(int intvalue, byte[] bytedata, int i) {
bytedata[i] = (byte) (intvalue >>> 24);
bytedata[i + 1] = (byte) (intvalue >>> 16);
bytedata[i + 2] = (byte) (intvalue >>> 8);
bytedata[i + 3] = (byte) intvalue;
}

// 将字节转换为十六进制字符串
private static string bytetohexstring(byte ib) {
char[] digit = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
'd', 'e', 'f'
};
char[] ob = new char[2];
ob[0] = digit[(ib >>> 4) & 0x0f];
ob[1] = digit[ib & 0x0f];

string s = new string(ob);

return s;
}

// 将字节数组转换为十六进制字符串
private static string bytearraytohexstring(byte[] bytearray) {
string strdigest = "";

for (int i = 0; i < bytearray.length; i++) {
strdigest += bytetohexstring(bytearray[i]);
}

return strdigest;
}
2010-12-17 11:46
0
雪    币: 157
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
[QUOTE=skyaegean;903984]不知道楼主用啥语言写的,一下是一段java代码,可以参考一下最后一段,将数组合并

public class sha1 {
private final int[] abcde = {
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2...[/QUOTE]

谢谢,我在写一个数字签名的代码,用的SHA-1用C写的,java我没学耶嘻嘻,下面是SHA-1的代码,能帮我想想连接五个分块的C代码么……
#include <STDIO.H>   
  
unsigned int state[5];   
unsigned int f1(unsigned int B, unsigned int C, unsigned int D)   
{   
    return (B&C)|(~B&D);   
}   
unsigned int f2(unsigned int B, unsigned int C, unsigned int D)   
{   
    return B^C^D;   
}   
unsigned int f3(unsigned int B, unsigned int C, unsigned int D)   
{   
    return (B&C)|(B&D)|(C&D);   
}   
unsigned int f4(unsigned int B, unsigned int C, unsigned int D)   
{   
    return B^C^D;   
}   

void Init()   
{   
    state[0] = 0x67452301;   
    state[1] = 0xefcdab89;   
    state[2] = 0x98badcfe;   
    state[3] = 0x10325476;   
    state[4] = 0xc3d2e1f0;   
}   

void shaTran(unsigned char * buf,unsigned int * state)   
{   
    int i,j;   
    unsigned int A,B,C,D,E,temp;
    unsigned int K[4];
    unsigned int W[80];
    unsigned char * p = (unsigned char *)W;  

    A  = state[0];   
    B  = state[1];   
    C  = state[2];   
    D  = state[3];   
    E  = state[4];   
         
    K[0] = 0x5a827999;   
    K[1] = 0x6ed9eba1;   
    K[2] = 0x8f1bbcdc;   
    K[3] = 0xca62c1d6;   

    for(i=0;i<16;i++)   
    {   
        j = 4*i;   
        p[j+3] = buf[j];   
        p[j+2] = buf[j+1];   
        p[j+1] = buf[j+2];   
        p[j] = buf[j+3];   
    }   
   
    for(i=16;i<80;i++)   
    {   
        W[i] = ((W[i-16]^W[i-14]^W[i-8]^W[i-3])<<1) | ((W[i-16]^W[i-14]^W[i-8]^W[i-3])>>31);   
    }   
   
    for(i=0;i<20;i++)   
    {   
        temp = E + f1(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[0];   
        E = D;   
        D = C;   
        C = (B<<30)|(B>>2);   
        B = A;   
        A = temp;   
    }   
   
    for(i=20;i<40;i++)   
    {   
        temp = E + f2(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[1];   
        E = D;   
        D = C;   
        C = (B<<30)|(B>>2);   
        B = A;   
        A = temp;   
    }   
   
    for(i=40;i<60;i++)   
    {   
        temp = E + f3(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[2];   
        E = D;   
        D = C;   
        C = (B<<30)|(B>>2);   
        B = A;   
        A = temp;   
    }   
   
    for(i=60;i<80;i++)   
    {   
        temp = E + f4(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[3];   
        E = D;   
        D = C;   
        C = (B<<30)|(B>>2);   
        B = A;   
        A = temp;   
    }   
     
    state[0] += A;   
    state[1] += B;   
    state[2] += C;   
    state[3] += D;   
    state[4] += E;   
}   
   
     
void sha(unsigned char *buf, int len, unsigned int * state, unsigned int f1,unsigned int f2)   
{   
    int i;   
    unsigned int floop1,floop2;
    unsigned char flen[8];
    unsigned char *p1 = (unsigned char *)&floop1;   
    unsigned char *p2 = (unsigned char *)&floop2;   
    floop1 = f1;   
    floop2 = f2;   
    floop2 = floop2 + (unsigned int)(len*8);   
   
    printf("floop1 = %08x\n",floop1);   
    printf("floop2 = %08x\n",floop2);   

    for(i=0; i<4; i++)   
    {   
        flen[3-i] = *p1;   
        flen[7-i] = *p2;   
        p1++;   
        p2++;   
    }   
   
    if(len<56)   
    {   
        buf[len] = 0x80;   
        for(i=len+1; i<56; i++)   
        {   
            buf[i] = 0x00;   
        }   
   
        for(i=56; i<64; i++)   
        {   
            buf[i] = flen[i-56];   
        }   
   
        shaTran(buf,state);   
    }   
   
    else   
    {   
        buf[len] = 0x80;   
        for(i=len+1; i<64; i++)   
        {   
            buf[i] = 0x00;   
        }   
   
        shaTran(buf,state);   
   
        for(i=0; i<56; i++)   
            buf[i] = 0x00;   

        for(i=56; i<64; i++)   
        {   
            buf[i] = flen[i-56];   
        }   
   
        shaTran(buf,state);   
    }   
}   
   
int main()   
{   
    unsigned char buf[64];
    FILE * file;   
    int len;
    unsigned int floop1,floop2;
    floop1 = floop2 = 0;        
   
    Init();   
      
    if (!(file = fopen("a.txt", "rb")))   
    {   
        printf("can not open file!!!\n");   
        return -1;   
    }   
   
    while(!feof(file))   
    {   
        len=fread(buf,1,64,file);
           
        if(ferror(file))   
        {   
            printf("read file error!!!\n");   
            return -1;   
        }   
           
        if(len == 64)   
        {   
            if((floop1 == 0xffffffff) && (floop2 == 0xfffffe00))   
            {   
                printf("file larger than 2exp(64)");   
                return -1;   
            }   
            if(floop2 != 0xfffffe00)floop2+=512;   
            else   
            {   
                floop1++;   
                floop2 = 0;   
            }   
   
        shaTran(buf,state);   
        }   
     
        else   
        {   
            sha(buf,len,state,floop1,floop2);   
        }   
    }   
    printf("%08x %08x %08x %08x %08x\n",state[0],state[1],state[2],state[3],state[4]);     
    return 0;   
}
2010-12-17 21:34
0
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
state[0]^state[1]^state[2]^state[3]^state[4]不就行了。
2010-12-18 13:43
0
雪    币: 157
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
[QUOTE=exile;904362]state[0]^state[1]^state[2]^state[3]^state[4]不就行了。[/QUOTE]

state[0]^state[1]^state[2]^state[3]^state[4]得出一个32位的值来代替160位的消息摘要进行签名,是么?  我刚学数字签名,所以还不懂,很感谢你的回答
2010-12-19 11:53
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习学习学习
2010-12-22 07:12
0
游客
登录 | 注册 方可回帖
返回
//