在python中为Tor hidden service生成私钥和主机名

在python中为Tor hidden service生成私钥和主机名,python,openssl,tor,Python,Openssl,Tor,我在这里做错什么了吗?我想我的错误可能在base32编码步骤中使用的字母表中。Shallot使用“abcdefghijklmnopqrstuvwxyz234567”,但我完全不确定python使用的是什么,哈哈。我最终以艰难的方式弄明白了 导入操作系统 进口稀土 导入系统 进口gmpy2 导入多处理 从hashlib导入sha1 从base64导入B64编码,B32编码 从pyasn1.codec.der导入编码器 从队列导入Empty作为QueueEmpty 从pyasn1.type导入uni

我在这里做错什么了吗?我想我的错误可能在base32编码步骤中使用的字母表中。Shallot使用“abcdefghijklmnopqrstuvwxyz234567”,但我完全不确定python使用的是什么,哈哈。

我最终以艰难的方式弄明白了

导入操作系统
进口稀土
导入系统
进口gmpy2
导入多处理
从hashlib导入sha1
从base64导入B64编码,B32编码
从pyasn1.codec.der导入编码器
从队列导入Empty作为QueueEmpty
从pyasn1.type导入univ,命名为type
####从原来的葱中偷来的常量####
EMIN=0x10001
EMAX=0xFFFFFFFF
####RSA的素数查找####
def random(贝特斯):
''生成一个随机数,其字节数为*8位。''
返回gmpy2.mpz(reduce(lambda,b:(a2**)(k/2-100):
返回n
返回0
#####编码材料#####
#https://tools.ietf.org/html/rfc3447#appendix-A.1
公开密钥类(大学顺序):
componentType=namedtype.NamedTypes(
namedtype.namedtype('modules',univ.Integer()),
namedtype.namedtype('publicExponent',univ.Integer())
)
等级RSA私钥(大学顺序):
componentType=namedtype.NamedTypes(
namedtype.namedtype('version',univ.Integer()),
namedtype.namedtype('modules',univ.Integer()),
namedtype.namedtype('publicExponent',univ.Integer()),
namedtype.namedtype('privateExponent',univ.Integer()),
namedtype.namedtype('prime1',univ.Integer()),
namedtype.namedtype('prime2',univ.Integer()),
namedtype.namedtype('exponent1',univ.Integer()),
namedtype.namedtype('exponent2',univ.Integer()),
namedtype.namedtype('系数',univ.Integer())
)
def公钥(n,e):
公钥=RSAPublicKey()
公钥setComponentByName('module',n)
public_key.setComponentByName('publicExponent',e)
返回编码器。编码(公钥)
def制造洋葱(n,e):
返回b32encode(sha1(公钥(n,e)).digest())[:16].lower()+'.onion'
def私钥(n、e、d、p、q):
私钥=RSAPrivateKey()
私钥.setComponentByName('version',0)
私钥setComponentByName('module',n)
私钥.setComponentByName('publicExponent',e)
私钥.setComponentByName('privateExponent',d)
私钥setComponentByName('prime1',p)
私钥setComponentByName('prime2',q)
私钥setComponentByName('exponent1',d%(p-1))
私钥setComponentByName('exponent2',d%(q-1))
private_key.setComponentByName('系数',gmpy2.invert(q,p))
返回编码器。编码(私钥)
def pprint_私钥(私钥):
打印'-'*5+'开始RSA私钥'+'-'*5
编码=B64编码(私钥)
编码时:
块,已编码=已编码[:64],已编码[64:]
打印块
打印'-'*5+'结束RSA私钥'+'-'*5
####辅助进程生成密钥、哈希和模式检查####
类工作者(多处理.Process):
定义初始值(self、regex、results、trials、kill、*args、**kwds):
多处理.Process.\uuuuu init\uuuuu(self,*args,**kwds)
self.regex=regex
self.results=结果
自我审判
自我毁灭
def运行(自):
pattern=re.compile(self.regex)
search=pattern.search
i=0
尽管如此:
p=查找_素数()
q=查找_素数()
如果q>p:
p、 q=q,p
n=良好的配对(p,q)
如果不是n:
持续
tot=n-(p+q-1)
e=EMIN
当e
您的错误是使用私钥计算哈希,您应该使用公钥

crypto.dump\u publickey(crypto.FILETYPE\u ASN1,keys)
的输出结构如下:

import os
import re
import sys
import gmpy2
import multiprocessing
from hashlib import sha1
from base64 import b64encode, b32encode
from pyasn1.codec.der import encoder
from Queue import Empty as QueueEmpty
from pyasn1.type import univ, namedtype

#### Constants stolen from the original shallot ####
EMIN = 0x10001
EMAX = 0xFFFFFFFFFF

#### Prime finding stuff for RSA ####
def random(bytez):
    '''Produces a random number thats has bytez*8 amount of bits.'''
    return gmpy2.mpz(reduce(lambda a, b: (a << 8)|ord(b), os.urandom(bytez), 0))

def good_prime(p):
    '''True if highly probably prime, else false.'''
    return gmpy2.is_prime(p, 1000) and \
           gmpy2.is_strong_bpsw_prp(p)

def find_prime(bytez=128):
    '''Checks random numbers for primality'''
    p = random(bytez)|1
    while not good_prime(p):
        p = random(bytez)|1
    return p

def good_pair(p, q):
    '''Returns p*q if p and q are a good pair, else 0.'''
    n = p*q
    k = gmpy2.ceil(gmpy2.log2(n))
    if abs(p - q) > 2**(k/2 - 100):
        return n
    return 0

##### Encoding stuffs #####
#https://tools.ietf.org/html/rfc3447#appendix-A.1
class RSAPublicKey(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('modulus', univ.Integer()),
        namedtype.NamedType('publicExponent', univ.Integer())
        )

class RSAPrivateKey(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('version', univ.Integer()),
        namedtype.NamedType('modulus', univ.Integer()),
        namedtype.NamedType('publicExponent', univ.Integer()),
        namedtype.NamedType('privateExponent', univ.Integer()),
        namedtype.NamedType('prime1', univ.Integer()),
        namedtype.NamedType('prime2', univ.Integer()),
        namedtype.NamedType('exponent1', univ.Integer()),
        namedtype.NamedType('exponent2', univ.Integer()),
        namedtype.NamedType('coefficient', univ.Integer())
        )

def public_key(n, e):
    public_key = RSAPublicKey()
    public_key.setComponentByName('modulus', n)
    public_key.setComponentByName('publicExponent', e)
    return encoder.encode(public_key)

def make_onion(n, e):
    return b32encode(sha1(public_key(n, e)).digest())[:16].lower()+'.onion'

def private_key(n, e, d, p, q):
    private_key = RSAPrivateKey()
    private_key.setComponentByName('version', 0)
    private_key.setComponentByName('modulus', n)
    private_key.setComponentByName('publicExponent', e)
    private_key.setComponentByName('privateExponent', d)
    private_key.setComponentByName('prime1', p)
    private_key.setComponentByName('prime2', q)
    private_key.setComponentByName('exponent1', d % (p - 1))
    private_key.setComponentByName('exponent2', d % (q - 1))
    private_key.setComponentByName('coefficient', gmpy2.invert(q, p))
    return encoder.encode(private_key)

def pprint_privkey(privkey):
    print '-'*5 + 'BEGIN RSA PRIVATE KEY' + '-'*5
    encoded = b64encode(privkey)
    while encoded:
        chunk, encoded = encoded[:64], encoded[64:]
        print chunk
    print '-'*5 + 'END RSA PRIVATE KEY' + '-'*5

#### Worker process generates keys, hashes, and checks for patterns ####
class Worker(multiprocessing.Process):

    def __init__(self, regex, results, trials, kill, *args, **kwds):
        multiprocessing.Process.__init__(self, *args, **kwds)
        self.regex = regex
        self.results = results
        self.trials = trials
        self.kill = kill

    def run(self):
        pattern = re.compile(self.regex)
        search = pattern.search
        i = 0
        while True:
            p = find_prime()
            q = find_prime()
            if q > p:
                p, q = q, p
            n = good_pair(p, q)
            if not n:
                continue
            tot = n - (p + q - 1)
            e = EMIN
            while e < EMAX:
                if self.kill.is_set():
                    self.trials.put(i)
                    return
                i += 1
                onion = make_onion(n, e)
                if search(onion) and gmpy2.gcd(e, tot)==1:
                    d = gmpy2.invert(e, tot)
                    priv = private_key(n, e, d, p, q)
                    self.results.put(onion+priv)
                    self.trials.put(i)
                    self.kill.set()
                    return
                e += 2

def kill_procs(processes, results, trials, kill):
    '''joins all processes, empties all queues, and returns sum of trials.'''
    if not kill.is_set():
        kill.set()
    sum_trials = 0
    while not trials.empty():
        sum_trials += trials.get()
    for proc in processes:
        proc.join()
    while not results.empty():
        results.get()
    return sum_trials

#### Main thread ####
def main(pattern):
    results = multiprocessing.Queue()
    trials = multiprocessing.Queue()
    kill = multiprocessing.Event()
    processes = []
    for i in range(multiprocessing.cpu_count()):
        processes.append(Worker(pattern, results, trials, kill))
        processes[-1].start()
    try:
        while True:
            try:
                found = results.get(True, 0.1)
            except QueueEmpty:
                pass
            else:
                break
    except KeyboardInterrupt:
        sum_trials = kill_procs(processes, results, trials, kill)
        print 'Tried', sum_trials, 'public keys before exit'
        sys.exit(1)
    sum_trials = kill_procs(processes, results, trials, kill)
    onion = found[:22]
    privkey = found[22:]
    print '-'*64
    print 'Found matching pattern after', sum_trials, 'tries:', onion
    print '-'*64
    pprint_privkey(privkey)

if __name__ == '__main__':
    try:
        main(sys.argv[1])
    except KeyboardInterrupt:
        sys.exit(1)
但是Tor只使用最后一个序列,因此您必须从22个字节开始切片:

    SEQUENCE (2 elem)
        SEQUENCE (2 elem)
            OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
            NULL
        BIT STRING (1 elem)
            SEQUENCE(2 elem)
                INTEGER (1024 bit) 1669234523452435234253452...
                INTEGER 65537
    SEQUENCE (2 elem)
        SEQUENCE (2 elem)
            OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
            NULL
        BIT STRING (1 elem)
            SEQUENCE(2 elem)
                INTEGER (1024 bit) 1669234523452435234253452...
                INTEGER 65537
pub_key = crypto.dump_publickey(crypto.FILETYPE_ASN1, keys)[22:]
key_hash = b32(hashlib.sha1(pub_key).digest()[:16])
print(key_hash[:16].lower() + ".onion")