2012-06-07 21 views
3

我想为SHA校验和生成类似VisualHostKey的东西。但它应该与任何十六进制校验和一起工作。校验和的可视表示算法(例如SHA)

生成的工件可能是ASCII艺术,2D调色板,或者只是PNG中的一些随机垃圾。我个人喜欢VisualHostKey的方法,但我很乐意提供建议。

这个想法是能够快速识别两个校验和是相同的,只用人眼。当遇到一大笔钱时,快速找到你要找的那个。

+1

您将很难将160位附近的任何东西压入图像中,以便它们易于记忆和区分。 – CodesInChaos

+0

相关概念:[Identicons](http://www.codinghorror.com/blog/2007/01/identicons-for-net.html)例如以独角兽形式http://unicornify.appspot.com/ – CodesInChaos

+1

呃,耻辱你让我看看@CodeInChaos :)虽然这是一个有趣的方法,虽然有点太多[OMG !!!小马!!!](http://upload.wikimedia.org/wikipedia/en/c/c2/Slashdot_omgponies.png)给我。 –

回答

0

一般来说,这是通过制作一种接受种子的图像生成函数来完成的。然后,您可以散列一些数据,然后为结果生成图像生成器。这将防止它在PNG中制作随机垃圾,并会给你一些区别。

+0

你的回答太笼统了,它完全没用IMO。有趣的部分是如何以一种可以被人类记住和区分的方式获取尽可能多的信息到图像中。 – CodesInChaos

+0

您是否期望我用完整的函数和代码示例给出答案?如果是这样,你需要相当多的代码和一些认真致力于首先确定功能的东西。据我所知,这是一项很多工作,并没有公布和广泛采用。在我看来,除非你有一组固定的图像和地图哈希值,否则整个事情都不实用。 –

1

您可以使用实际的OpenSSH VisualHostKey代码,该代码位于文件中的key_fingerprint_randomart()函数中。该算法非常简单,可以将任何字节数组作为输入。在OpenSSH中,输入是密钥的加密散列;你可以做同样的事情。

(如在OpenSSH的源代码中定义,该函数还需要一个指针到该键结构体本身,但是这仅用于打印在图片的顶部的键的类型和大小。)

事实上,由于代码是免费许可的,所以请在这里附上一份副本。这是从OpenSSH的6.1,$OpenBSD: key.c,v 1.99 2012/05/23 03:28:28 djm Exp $萃取:

/* 
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 
* Copyright (c) 2008 Alexander von Gernler. All rights reserved. 
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions 
* are met: 
* 1. Redistributions of source code must retain the above copyright 
* notice, this list of conditions and the following disclaimer. 
* 2. Redistributions in binary form must reproduce the above copyright 
* notice, this list of conditions and the following disclaimer in the 
* documentation and/or other materials provided with the distribution. 
* 
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
*/ 

/* 
* Draw an ASCII-Art representing the fingerprint so human brain can 
* profit from its built-in pattern recognition ability. 
* This technique is called "random art" and can be found in some 
* scientific publications like this original paper: 
* 
* "Hash Visualization: a New Technique to improve Real-World Security", 
* Perrig A. and Song D., 1999, International Workshop on Cryptographic 
* Techniques and E-Commerce (CrypTEC '99) 
* sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf 
* 
* The subject came up in a talk by Dan Kaminsky, too. 
* 
* If you see the picture is different, the key is different. 
* If the picture looks the same, you still know nothing. 
* 
* The algorithm used here is a worm crawling over a discrete plane, 
* leaving a trace (augmenting the field) everywhere it goes. 
* Movement is taken from dgst_raw 2bit-wise. Bumping into walls 
* makes the respective movement vector be ignored for this turn. 
* Graphs are not unambiguous, because circles in graphs can be 
* walked in either direction. 
*/ 

/* 
* Field sizes for the random art. Have to be odd, so the starting point 
* can be in the exact middle of the picture, and FLDBASE should be >=8 . 
* Else pictures would be too dense, and drawing the frame would 
* fail, too, because the key type would not fit in anymore. 
*/ 
#define FLDBASE   8 
#define FLDSIZE_Y  (FLDBASE + 1) 
#define FLDSIZE_X  (FLDBASE * 2 + 1) 
static char * 
key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) 
{ 
     /* 
     * Chars to be used after each other every time the worm 
     * intersects with itself. Matter of taste. 
     */ 
     char *augmentation_string = " .o+=*[email protected]%&#/^SE"; 
     char *retval, *p; 
     u_char field[FLDSIZE_X][FLDSIZE_Y]; 
     u_int i, b; 
     int  x, y; 
     size_t len = strlen(augmentation_string) - 1; 

     retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); 

     /* initialize field */ 
     memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); 
     x = FLDSIZE_X/2; 
     y = FLDSIZE_Y/2; 

     /* process raw key */ 
     for (i = 0; i < dgst_raw_len; i++) { 
       int input; 
       /* each byte conveys four 2-bit move commands */ 
       input = dgst_raw[i]; 
       for (b = 0; b < 4; b++) { 
         /* evaluate 2 bit, rest is shifted later */ 
         x += (input & 0x1) ? 1 : -1; 
         y += (input & 0x2) ? 1 : -1; 

         /* assure we are still in bounds */ 
         x = MAX(x, 0); 
         y = MAX(y, 0); 
         x = MIN(x, FLDSIZE_X - 1); 
         y = MIN(y, FLDSIZE_Y - 1); 

         /* augment the field */ 
         if (field[x][y] < len - 2) 
           field[x][y]++; 
         input = input >> 2; 
       } 
     } 

     /* mark starting point and end point*/ 
     field[FLDSIZE_X/2][FLDSIZE_Y/2] = len - 1; 
     field[x][y] = len; 

     /* fill in retval */ 
     snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k)); 
     p = strchr(retval, '\0'); 

     /* output upper border */ 
     for (i = p - retval - 1; i < FLDSIZE_X; i++) 
       *p++ = '-'; 
     *p++ = '+'; 
     *p++ = '\n'; 

     /* output content */ 
     for (y = 0; y < FLDSIZE_Y; y++) { 
       *p++ = '|'; 
       for (x = 0; x < FLDSIZE_X; x++) 
         *p++ = augmentation_string[MIN(field[x][y], len)]; 
       *p++ = '|'; 
       *p++ = '\n'; 
     } 

     /* output lower border */ 
     *p++ = '+'; 
     for (i = 0; i < FLDSIZE_X; i++) 
       *p++ = '-'; 
     *p++ = '+'; 

     return retval; 
} 

它似乎没有从const Key *k参数,这是只在一行作为参数对OpenSSH的代码的其余部分的显著依存关系,一边到key_type()key_size()函数(或宏?)。非标准类型u_charu_int看起来分别只是unsigned charunsigned int的别名,而xcalloc()函数似乎只是标准calloc()的替代或包装。