Encryption 散列RSA密钥的标准方法?

Encryption 散列RSA密钥的标准方法?,encryption,hash,rsa,public-key-encryption,public-key,Encryption,Hash,Rsa,Public Key Encryption,Public Key,创建RSA公钥哈希(sha-1或MD5)的算法是什么?有没有标准的方法可以做到这一点?散列只是模数,字符串两者相加,然后取散列?通常使用SHA-1还是MD5 我想用它来确保我得到了正确的密钥(让发送方发送一个散列,我自己计算),并记录所说的散列,以便我总是知道加密有效负载时使用的确切密钥。基于OpenSSH源代码,为RSA密钥生成指纹的方法是将公钥中的n和e转换为big-endian二进制数据,连接数据,然后使用给定的散列函数散列该数据 下面是OpenSSH源代码的一部分。添加这些评论是为了澄清

创建RSA公钥哈希(sha-1或MD5)的算法是什么?有没有标准的方法可以做到这一点?散列只是模数,字符串两者相加,然后取散列?通常使用SHA-1还是MD5


我想用它来确保我得到了正确的密钥(让发送方发送一个散列,我自己计算),并记录所说的散列,以便我总是知道加密有效负载时使用的确切密钥。

基于OpenSSH源代码,为RSA密钥生成指纹的方法是将公钥中的n和e转换为big-endian二进制数据,连接数据,然后使用给定的散列函数散列该数据

下面是OpenSSH源代码的一部分。添加这些评论是为了澄清正在发生的事情

// from key_fingerprint_raw() in key.c
switch (k->type) {
case KEY_RSA1:
    // figure out how long n and e will be in binary form
    nlen = BN_num_bytes(k->rsa->n);
    elen = BN_num_bytes(k->rsa->e);
    len = nlen + elen;
    // allocate space for n and e and copy the binary data into blob
    blob = xmalloc(len);
    BN_bn2bin(k->rsa->n, blob);
    BN_bn2bin(k->rsa->e, blob + nlen);

...

// pick a digest to use
switch (dgst_type) {
case SSH_FP_MD5:
    md = EVP_md5();
    break;
case SSH_FP_SHA1:
    md = EVP_sha1();
    break;

...

// hash the data in blob (n and e)
EVP_DigestInit(&ctx, md);
EVP_DigestUpdate(&ctx, blob, len);
EVP_DigestFinal(&ctx, retval, dgst_raw_length);
BN\u bn2bin


BN_bn2bin(a,to)
a
的绝对值转换为大端形式,并存储在
to
to
必须指向
BN\u num\u字节(a)
内存字节

这里用于散列密钥的方法不抗冲突。也就是说,很容易找到一个不同的对(n',e'),例如,通过从n中删除一个字节并将其附加到e中,使得生成的blob不会改变。攻击者甚至有相当大的机会可以将这样一个模数n'因子化,例如,如果n'的除一个素因子外的所有因子都很小。如果需要抗冲突,那么例如,两个整数n和e的长度应该编码到散列的字符串中,例如,通过使用字符串的DER编码。我不想在这里声称SSH在这里做错了什么。也就是说,它不依赖于密钥散列的抗冲突性。我也不知道OP是否需要一个防冲突散列,因为这个问题不够具体,无法确定攻击者是否可以找到另一个具有相同散列的密钥,从而利用它进行攻击。相反,仅仅挑选一些随机的代码片段并将其用于可能有不同需求的事情是一个坏主意。