代码之家  ›  专栏  ›  技术社区  ›  Petr Skocik

SHA1以流方式对长度前缀的消息进行校验和

  •  4
  • Petr Skocik  · 技术社区  · 6 年前

    Git sha是通过加前缀来计算的 "blob $DecimalMessageLength\0" 然后对带前缀的消息进行SHA1校验和。

    从SHA1算法的属性来看,是否有可能以流式方式来执行此操作,即在对消息体进行哈希处理之后预先添加前缀?

    C下面的示例(链接 -lcrypto 安装了libssl dev;这可能不是很有用,因为这一个甚至没有公开SHA1算法,但我在玩……:

    #include <openssl/sha.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int pr_dgst(unsigned char const Dgst[static SHA_DIGEST_LENGTH])
    {
        char const digits[]="0123456789abcdef";
        char digest_pr[(SHA_DIGEST_LENGTH)*2+1];
        for(size_t i=0;i<SHA_DIGEST_LENGTH;i++){
            digest_pr[i*2+0]=digits[Dgst[i]/16];
            digest_pr[i*2+1]=digits[Dgst[i]%16];
        }
        digest_pr[(SHA_DIGEST_LENGTH)*2]='\0';
        return puts(digest_pr);
    }
    
    int main()
    {
        system("echo gitsha; printf '%s' 'abc' | git hash-object --stdin");
        #define STR_STRLEN(A) A, (sizeof(A)/sizeof(*(A))-1) //paste string literal and its length
    
        unsigned char digest[SHA_DIGEST_LENGTH];
        SHA_CTX ctx;
        SHA1_Init(&ctx); SHA1_Update(&ctx,STR_STRLEN("blob 3\0abc")); SHA1_Final(digest,&ctx);
        pr_dgst(digest); //prints the same as the system command
    
        //do this in a streaming fashion??
        SHA1_Init(&ctx); 
        size_t len = 0;
        SHA1_Update(&ctx,STR_STRLEN("a")); len++;
        SHA1_Update(&ctx,STR_STRLEN("b")); len++;
        SHA1_Update(&ctx,STR_STRLEN("c")); len++;
        //"prepend" "blob 3\0" now?
        SHA1_Final(digest,&ctx);
        /*pr_dgst(digest);*/
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  4
  •   Antti Haapala -- Слава Україні    6 年前

    只能将字节添加到 消息流的结尾

    一个 有一个 前缀 对于2个文件,您可以存储 2 files with a known bare SHA-1 collision into the same repository and they would get different blob IDs