5

我们正在生成 rsa 密钥,并希望将它们存储为公共和私有 base64 哈希,就像我习惯在我的 Linux 机器上的 ~/.ssh 文件夹中看到的那样。

但是,我们正在处理 RSA 原语 - n、e 和 d 值。

如何从这些值中生成 base64 散列?反之亦然(如果不明显)。

4

3 回答 3

2

base64 是一种用于表示为文本的二进制数据的编码方案,而不是散列算法。如果你指的是指纹,那就是MD5。

对于指纹和 base64 编码的数据,您可以查阅甚至重用Twisted 的 Conch 实现

于 2012-04-17T08:16:08.553 回答
1

您需要使用正确的 ASN.1 编码,然后使用 base64。

不幸的是,我不知道正确的 ASN.1 编码是什么(我自己也不太了解 ASN.1)。它内置于 openssl,但我找不到从命令行访问它的方法。您可以使用http://www.openssl.org/docs/crypto/RSA_print.htmlhttp://www.openssl.org/docs/crypto/rsa.html从 C 编写它

标签中有python。pyopenssl 包装了 openssl 并可能提供更简单的路径 - https://code.launchpad.net/pyopenssl - 但从源代码来看,它们似乎太高级了(它们似乎没有暴露 RSA 结构)。

如果你说 ASN.1(或者有一个这样做的库,比如http://pyasn1.sourceforge.net/)那么这可能就是你所需要的 - https://polarssl.org/kb/cryptography/asn1-key -结构在der-and-pem

(我意识到这是相当不完整的——我不是在寻找赏金,只是倾倒我所知道的,以防它足以提供帮助——基本上“ASN.1 for DER”是你所缺少的部分;它定义了结构以便在回读时可以将不同的部分分开)

于 2013-11-04T23:15:43.747 回答
1

几个小时后有空时,我会用更多细节和解码器更新它。

def bitlength_and_integer_in_bytes(n):
    bytes_length = n.bit_length()//8+1
    return bytes_length.to_bytes(4, "big")+n.to_bytes(bytes_length, "big")

def gen_id_rsa_pub(n,e):
    return b"ssh-rsa "+base64.b64encode(b"\x00\x00\x00\x07ssh-rsa"+bitlength_and_integer_in_bytes(e)+bitlength_and_integer_in_bytes(n))+b" RSA key description"
open("id_rsa.pub", "bw").write(gen_id_rsa_pub(n,e))
##import base64
##from pyasn1.codec.der import decoder
##s = "\n".join(open(".ssh/id_rsa").readlines()[1:-1])
##d = decoder.decode(base64.b64decode(s))
import base64
from pyasn1.codec.der import encoder
from pyasn1.type.univ import *
#below from http://stackoverflow.com/a/9758173/443348
def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m

#got example values from https://en.wikipedia.org/wiki/RSA_(algorithm)#A_working_example
p = 61
q = 53
n = p*q #3233
totient_n = (p-1)*(q-1) # 3120
e = 17 # Should be coprime to 3120
d = modinv(e, totient_n) #2753

s = Sequence()
def setvalues(sequence, values):
    for index, value in enumerate(values):
        sequence.setComponentByPosition(index, value)

q = n/p

setvalues(s, map(Integer, (0, n, e, d, p, q, d%(p-1), d%(q-1), modinv(q,p))))
id_rsa = b"-----BEGIN RSA PRIVATE KEY-----\n"+base64.b64encode(encoder.encode(s))+b"\n-----END RSA PRIVATE KEY-----\n"
open("id_rsa", "bw").write(id_rsa)
于 2013-11-05T11:22:23.393 回答