diff options
author | adrien1018 <adrien1018@users.noreply.github.com> | 2019-06-09 11:38:40 +0800 |
---|---|---|
committer | adrien1018 <adrien1018@users.noreply.github.com> | 2019-06-09 11:38:40 +0800 |
commit | 4f012eb453bfe6376fc7c119dec4e048fbefd9ab (patch) | |
tree | 6af0bba9321113c1bc837e22cfa254eb3295892d | |
parent | 7f8531a76356f7c8332ee816c0e35cd974c80f5f (diff) | |
download | cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.gz cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.bz2 cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.lz cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.xz cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.zst cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.zip |
Revise key generator & add data fetching
-rwxr-xr-x | forge_key.py | 55 | ||||
-rwxr-xr-x | get_data.py | 37 |
2 files changed, 62 insertions, 30 deletions
diff --git a/forge_key.py b/forge_key.py index 7fbd46d..850f2b1 100755 --- a/forge_key.py +++ b/forge_key.py @@ -17,7 +17,7 @@ def main(): # Generate RSA key pair data_len = 100 data = random.getrandbits(data_len * 8).to_bytes(data_len, 'little') - print(data) + print('Data:', base64.b64encode(data).decode()) key = forge_rsa_key(data) # Public hidden service @@ -49,35 +49,34 @@ NONCE_LEN = 200 KEY_LEN = 1024 def forge_rsa_key(data: bytes): - # Generate RSA key with p=3. + # Generate RSA key with p = 11. # By Cramer's conjecture (which is likely to be true), - # the maximum prime gap for a 1024-bit number should be around 5*10**5. - # We choose a 800-bit data size, and a 200-bit nonce, which allows a maximum - # gap of 2^(1023-1000)/5 ~ 10**6 and a collision probability of 2^(-100). + # the maximum prime gap for a 1024-bit number should be around 500000. + # We choose a 800-bit data size and a 200-bit nonce, which allows a maximum + # gap of 2^(1023-1000)/11 ~ 760000 and a collision probability of ~2^(-100). assert(len(data) == DATA_LEN // 8) # let the highest bit be 1 - n_expect = 1 << (KEY_LEN - 1) | \ - int.from_bytes(data, 'little') << (KEY_LEN - 1 - DATA_LEN) | \ - random.getrandbits(NONCE_LEN) << (KEY_LEN - 1 - DATA_LEN - NONCE_LEN) while True: - p = 5 - q = next_prime((n_expect - 1) // p + 1) - n = p * q - # final (paranoid) correctness check, - # should be true given the conjecture is true - if (n >> (KEY_LEN - 1 - DATA_LEN)) == \ - (n_expect >> (KEY_LEN - 1 - DATA_LEN)): break - - # Compute RSA components - e = 65537 - d = int(gmpy2.invert(e, (p - 1) * (q - 1))) - - # Library reference - # https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html - key = RSA.construct( - (n, e, d), - consistency_check=True, - ) + n_expect = 1 << (KEY_LEN - 1) | \ + int.from_bytes(data, 'little') << (KEY_LEN - 1 - DATA_LEN) | \ + random.getrandbits(NONCE_LEN) << (KEY_LEN - 1 - DATA_LEN - NONCE_LEN) + while True: + p = 11 + q = next_prime((n_expect - 1) // p + 1) + n = p * q + # final (paranoid) correctness check, + # should be true given the conjecture is true + if (n >> (KEY_LEN - 1 - DATA_LEN)) == \ + (n_expect >> (KEY_LEN - 1 - DATA_LEN)): break + # Compute RSA components + e = 65537 + d = int(gmpy2.invert(e, (p - 1) * (q - 1))) + # Library reference + # https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html + # if get an invalid key (prob ~1/11), retry with another nonce + try: key = RSA.construct((n, e, d), consistency_check=True) + except ValueError: continue + break # Tor accepts DER-encoded, then base64 encoded RSA key # https://github.com/torproject/tor/blob/a462ca7cce3699f488b5e2f2921738c944cb29c7/src/feature/control/control_cmd.c#L1968 @@ -85,9 +84,5 @@ def forge_rsa_key(data: bytes): ret = str(base64.b64encode(der), 'ASCII') return ret -def data_from_public_key(n): - data_num = (n - (1 << (KEY_LEN - 1))) >> (KEY_LEN - 1 - DATA_LEN) - return data_num.to_bytes(DATA_LEN // 8, 'little') - if __name__ == '__main__': main() diff --git a/get_data.py b/get_data.py new file mode 100755 index 0000000..e509180 --- /dev/null +++ b/get_data.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +import argparse +import os, sys +import shutil +import base64 +import random + +import gmpy2 +import asn1 +from Crypto.PublicKey import RSA +from stem.control import Controller + + +def main(name): + controller = Controller.from_port() + controller.authenticate() + a = str(controller.get_hidden_service_descriptor(name)) + public = a[a.find('PUBLIC KEY-----')+15:a.find('-----END')].replace('\n', '') + decoder = asn1.Decoder() + decoder.start(base64.b64decode(public)) + decoder.start(decoder.read()[1]) + data = data_from_public_key(decoder.read()[1]) + print(base64.b64encode(data).decode()) + +DATA_LEN = 800 +NONCE_LEN = 200 +KEY_LEN = 1024 + +def data_from_public_key(n): + data_num = (n - (1 << (KEY_LEN - 1))) >> (KEY_LEN - 1 - DATA_LEN) + return data_num.to_bytes(DATA_LEN // 8, 'little') + +if __name__ == '__main__': + if len(sys.argv) < 2: + print(sys.argv[0], '[hidden service name]') + sys.exit(1) + main(sys.argv[1]) |