2012-04-17 185 views
5

我們正在生成rsa密鑰,並希望將它們存儲爲公共和私有的base64哈希值,就像我習慣在我的〜/ .ssh文件夾中看到的那樣linux盒子。從NED生成序列化的rsa公鑰/私鑰Big Ints

但是,我們正在處理RSA原語 - n,e和d值。

如何從這些值中生成base64散列?反之亦然(如果它不明顯)。

+0

爲什麼不能http://docs.python.org/3.4/library/base64.html和/或(https://pypi.python.org/pypi/rsa http://stuvel.eu/ rsa)? – user2284570 2013-10-29 20:21:43

+0

@ J.Random任何答案? – user2284570 2013-11-02 20:48:02

回答

2

base64是用於表示爲文本而不是散列算法的二進制數據的編碼方案。如果您指的是指紋,那是MD5。

對於指紋和base64編碼數據,您可以諮詢或甚至重複使用Twisted's Conch implementation

1

你需要使用正確的ASN.1編碼,然後base64。

不幸的是,我不知道什麼是正確的ASN.1編碼(我自己並不真正理解ASN.1)。它內置於openssl,但我找不到從命令行訪問它的方法。你可以用C編寫,使用http://www.openssl.org/docs/crypto/RSA_print.htmlhttp://www.openssl.org/docs/crypto/rsa.html

你在代碼中有python。 pyopenssl包裝openssl並可能提供一個更簡單的路徑 - https://code.launchpad.net/pyopenssl - 但看看源代碼看起來他們似乎太高級別(他們似乎沒有公開RSA結構)。

如果你講ASN.1(或有這樣做,就像http://pyasn1.sourceforge.net/庫),那麼這可能是你所需要的 - https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem

(我知道這是相當不完整的 - 我不是在尋找的賞金,只是傾銷我知道的情況下足以提供幫助 - 基本上「DER的ASN.1」就是你缺少的位;它是什麼定義了結構,以便在讀回時可以分離出不同的部分)

+0

然而,公鑰id_rsa.pub具有不同的格式,請參閱我的答案(它將隨細節更新)。 – 2013-11-05 11:22:55

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)