def dh1_handler(): exp = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES) public = nacl.crypto_scalarmult_curve25519_base(exp) (sys.stdout.buffer if hasattr(sys.stdout, 'buffer') else sys.stdout).write(b"public component " + b85encode(public) + b'\n') (sys.stdout.buffer if hasattr(sys.stdout, 'buffer') else sys.stdout).write(b"secret exponent " + b85encode(exp) + b'\n') clearmem(exp)
def dh2_handler(peer): exp = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES) public = nacl.crypto_scalarmult_curve25519_base(exp) (sys.stdout.buffer if hasattr(sys.stdout, 'buffer') else sys.stdout).write(b"public component " + b85encode(public) + b'\n') secret = nacl.crypto_scalarmult_curve25519(exp, b85decode(peer)) (sys.stdout.buffer if hasattr(sys.stdout, 'buffer') else sys.stdout).write(b"shared secret " + b85encode(secret) + b'\n') clearmem(secret) clearmem(exp)
def test(): p1 = MPECDH(4) p2 = MPECDH(4) p3 = MPECDH(4) p4 = MPECDH(4) # four way p3.mpecdh2(p2.mpecdh2(p1.mpecdh2(p4.mpecdh1(p3.mpecdh1(p2.mpecdh1(p1.mpecdh1())))))) print 1, b85encode(p1.secret) print 2, b85encode(p2.secret) print 3, b85encode(p3.secret) print 4, b85encode(p4.secret)
def __repr__(self): return "name: %s\nkeyid: %s\nvalid: %s - %s\nmp: %s\nms: %s\n" \ "cp: %s\ncs: %s\nsp: %s\nss: %s\n" % (self.name, self.keyid(), self.created.isoformat(), self.valid.isoformat(), b85encode(self.mp), self.ms is not None, b85encode(self.cp), self.cs is not None, b85encode(self.sp), self.ss is not None)
def export_handler(self, basedir=None): # exports key self from basedir, outputs to stdout, key is ascii armored keys = publickey.Identity(self, basedir=basedir) dates='{:<32}{:<32}'.format(keys.created.isoformat(), keys.valid.isoformat()) pkt = keys.sign(keys.mp+keys.sp+keys.cp+dates+keys.name, master=True) keys.clear() return b85encode(pkt, True)
def _2user(): # 1st user exp1 = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES) public1 = nacl.crypto_scalarmult_curve25519_base(exp1) #print "public1: \t%s\nexp1: \t%s" % (b85encode(public1), b85encode(exp1)) print() # 2nd user exp2 = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES) public2 = nacl.crypto_scalarmult_curve25519_base(exp2) key = nacl.crypto_scalarmult_curve25519(exp2, public1) print("key: \t%s" % (b85encode(key))) #print "public2: \t%s\nkey: \t%s" % (b85encode(public2), b85encode(key)) print() # 1st user completing DH key = nacl.crypto_scalarmult_curve25519(exp1, public2) print("key: \t%s" % (b85encode(key)))
def print_keys(keys): for n,i in keys.items(): print n print '\t%s' % '\n\t'.join([b85encode(x) for x in i][-3:]) if len(i)>3: print ' has', len(i)-3, 'more keys...' print
def export_handler(self, basedir=None): # exports key self from basedir, outputs to stdout, key is ascii armored keys = publickey.Identity(self, basedir=basedir) dates = '{:<32}{:<32}'.format(keys.created.isoformat(), keys.valid.isoformat()) pkt = keys.sign(keys.mp + keys.sp + keys.cp + dates + keys.name, master=True) keys.clear() return b85encode(pkt, True)
def buffered_sign(self,infd,outfd, armor=None): # calculate hash sum of data state = nacl.crypto_generichash_init() while True: block = infd.read(BLOCK_SIZE) if not block.strip(): break state = nacl.crypto_generichash_update(state, block) outfd.write(block) hashsum = nacl.crypto_generichash_final(state) # sign hashsum sig = self.sign(hashsum)[:nacl.crypto_sign_BYTES] #print 'clearing' #self.clear() if armor: sig = "%s%s" % (SIGPREFIX, b85encode(sig)) outfd.write(sig)
def sign_handler(infile=None, outfile=None, self=None, basedir=None, armor=False): # provides a high level function to sign files # infile specifies the filename of the input file, # if '-' or not specified it uses stdin # outfile specifies the filename of the output file, # if unspecified but armor is, or if '-' or # infile is unspecified, then it uses stdout # otherwise it appends '.sig' to infile # armor instructs the function to output ascii # self specifies the sender for signing the message # basedir provides a root for the keystores # this function also handles buffering. fd = inputfd(infile) if (not outfile and armor) or outfile == '-' or (not infile or infile == '-'): outfd = sys.stdout else: outfd = open(outfile or infile+'.sig','w') # calculate hash sum of data state = nacl.crypto_generichash_init() while True: block = fd.read(BLOCK_SIZE) if not block.strip(): break state = nacl.crypto_generichash_update(state, block) outfd.write(block) hashsum = nacl.crypto_generichash_final(state) me = publickey.Identity(self, basedir=basedir) # sign hashsum sig = me.sign(hashsum)[:nacl.crypto_sign_BYTES] me.clear() if armor: sig = "%s%s" % (SIGPREFIX, b85encode(sig)) outfd.write(sig) if fd != sys.stdin: fd.close() if outfd != sys.stdout: outfd.close()
def sign_handler(infile=None, outfile=None, self=None, basedir=None, armor=False): if not infile or infile == '-': fd = sys.stdin.buffer if hasattr(sys.stdin, 'buffer') else sys.stdin else: fd = open(infile, 'rb') if (not outfile and armor) or outfile == '-': outfd = sys.stdout.buffer if hasattr(sys.stdout, 'buffer') else sys.stdout else: outfd = open(outfile or infile + '.sig', 'wb') # calculate hash sum of data state = nacl.crypto_generichash_init() while True: block = fd.read(BLOCK_SIZE) if not block.strip(): break state = nacl.crypto_generichash_update(state, block) outfd.write(block) hashsum = nacl.crypto_generichash_final(state) me = publickey.Identity(self, basedir=basedir) # sign hashsum sig = me.sign(hashsum)[:nacl.crypto_sign_BYTES] me.clear() if armor: outfd.write(SIGPREFIX) outfd.write(b85encode(sig)) else: outfd.write(sig) if fd != sys.stdin: fd.close() if outfd != sys.stdout: outfd.close()
def export_handler(self, basedir=None): # exports key self from basedir, outputs to stdout, key is ascii armored keys = publickey.Identity(self, basedir=basedir) pkt = keys.sign(keys.mp+keys.cp+keys.sp+keys.name, master=True) keys.clear() return b85encode(pkt)
ensure_self_specified(opts) chaining_decrypt_handler(opts.infile, outfile=opts.outfile, recipient=opts.recipient[0], self=opts.self, basedir=opts.basedir) # start ECDH elif opts.action=='d1': if PITCHFORK: ensure_recipient_specified(opts) pitchfork.init() params = pitchfork.start_ecdh(opts.recipient[0]) else: params = dh1_handler() if params: print "secret exponent", b85encode(params[0]) print "public component", b85encode(params[1]) clearmem(params[0]) # receive ECDH elif opts.action=='d2': ensure_dhparam_specified(opts) if PITCHFORK: ensure_recipient_specified(opts) pitchfork.init() params = pitchfork.resp_ecdh(opts.dh_param, opts.recipient[0]) else: params = dh2_handler(binascii.unhexlify(opts.dh_param)) if params: print "shared secret", b85encode(params[1]) print "public component", b85encode(params[0]) clearmem(params[0])
def main(): # main command line handler for pbp parser = argparse.ArgumentParser(description='pbp') group = parser.add_mutually_exclusive_group() group.add_argument('--gen-key', '-g', dest='action', action='store_const', const='g', help="generates a new key") group.add_argument('--encrypt', '-c', dest='action', action='store_const', const='c',help="encrypts") group.add_argument('--decrypt', '-d', dest='action', action='store_const', const='d',help="decrypts") group.add_argument('--sign', '-s', dest='action', action='store_const', const='s',help="signs") group.add_argument('--master-sign', '-m', dest='action', action='store_const', const='m',help="signs keys with your masterkey") group.add_argument('--verify', '-v', dest='action', action='store_const', const='v',help="verifies") group.add_argument('--hash', '-H', dest='action', action='store_const', const='h',help="hashes") group.add_argument('--list', '-l', dest='action', action='store_const', const='l',help="lists public keys") group.add_argument('--list-secret', '-L', dest='action', action='store_const', const='L',help="Lists secret keys") group.add_argument('--export-key', '-x', dest='action', action='store_const', const='x',help="export public key") group.add_argument('--import-key', '-X', dest='action', action='store_const', const='X',help="import public key") group.add_argument('--check-sigs', '-C', dest='action', action='store_const', const='C',help="lists all known sigs on a public key") group.add_argument('--fcrypt', '-e', dest='action', action='store_const', const='e',help="encrypts a message using PFS to a peer") group.add_argument('--fdecrypt', '-E', dest='action', action='store_const', const='E',help="decrypts a message using PFS to a peer") group.add_argument( '-D1', dest='action', action='store_const', const='d1',help="initiates an ECDH key exchange") group.add_argument( '-D2', dest='action', action='store_const', const='d2',help="responds to an ECDH key request") group.add_argument( '-D3', dest='action', action='store_const', const='d3',help="finalizes an ECDH key exchange") group.add_argument('--dh-start', '-Ds', dest='action', action='store_const', const='ds',help="initiates an ECDH key exchange") group.add_argument('--dh-end', '-De', dest='action', action='store_const', const='de',help="finalizes an ECDH key exchange") group.add_argument('--rand-stream', '-R', dest='action', action='store_const', const='R',help="generate arbitrary random stream") if PITCHFORK: parser.add_argument('--pitchfork', '-P', dest='PITCHFORK', action='store_const', const='P',help="arms PITCHFORK", default=False) parser.add_argument('--signature', '-z', help="sets the pitchfork sig to verify") parser.add_argument('--recipient', '-r', action='append', help="designates a recipient for public key encryption") parser.add_argument('--name', '-n', help="sets the name for a new key") parser.add_argument('--basedir', '-b', '--base-dir', help="set the base directory for all key storage needs", default=defaultbase) parser.add_argument('--self', '-S', help="sets your own key") parser.add_argument('--key', '-k', help="some password or secret") parser.add_argument('--dh-param', '-DP',help="public parameter for ECDH key exchange") parser.add_argument('--dh-exp', '-DE',help="secret exp for final step of a ECDH key exchange") parser.add_argument('--size', '-Rs',help="size of random stream to generate") parser.add_argument('--dh-peers', '-Dp',help="the number of peers participating in a ECDH key exchange") parser.add_argument('--infile', '-i', help="file to operate on") parser.add_argument('--armor', '-a', action='store_true', help="ascii armors the output") parser.add_argument('--outfile', '-o', help="file to output to") opts=parser.parse_args() opts.basedir=os.path.expandvars( os.path.expanduser(opts.basedir)) # Generate key if opts.action=='g': ensure_name_specified(opts) publickey.Identity(opts.name, create=True, basedir=opts.basedir) # list public keys elif opts.action=='l': if PITCHFORK: pitchfork.init() res = pitchfork.listkeys(opts.name) if(res): keys, stats = res pitchfork.print_keys(keys) pitchfork.storage_stats(stats, keys) else: print 'none' else: for i in publickey.get_public_keys(opts.basedir): print ('valid' if i.valid > datetime.datetime.utcnow() > i.created else 'invalid'), i.keyid(), i.name # list secret keys elif opts.action=='L': for i in publickey.get_secret_keys(opts.basedir): print ('valid' if i.valid > datetime.datetime.utcnow() > i.created else 'invalid'), i.keyid(), i.name # encrypt elif opts.action=='c': if PITCHFORK: ensure_recipient_specified(opts) pitchfork.init() res=pitchfork.encrypt(opts.recipient[0], infile=opts.infile, outfile=opts.outfile) if res: print >>sys.stderr, b85encode(res) return if opts.recipient or opts.self: ensure_self_specified(opts) ensure_recipient_specified(opts) encrypt_handler(infile=opts.infile, outfile=opts.outfile, recipient=opts.recipient, self=opts.self, basedir=opts.basedir) # decrypt elif opts.action=='d': if PITCHFORK: ensure_recipient_specified(opts) pitchfork.init() res=pitchfork.decrypt(opts.recipient[0], infile=opts.infile, outfile=opts.outfile) else: sender = decrypt_handler(infile=opts.infile, outfile=opts.outfile, self=opts.self, basedir=opts.basedir) if sender: print >>sys.stderr, 'good message from', sender # sign elif opts.action=='s': if PITCHFORK: ensure_recipient_specified(opts) pitchfork.init() res=pitchfork.sign(opts.recipient[0], infile=opts.infile, outfile=opts.outfile) if res: print >>sys.stderr, b85encode(res[0]), b85encode(res[1]) return ensure_self_specified(opts) sign_handler(infile=opts.infile, outfile=opts.outfile, self=opts.self, armor=opts.armor, basedir=opts.basedir) # verify elif opts.action=='v': if PITCHFORK: ensure_signature_specified(opts) ensure_recipient_specified(opts) pitchfork.init() res=pitchfork.verify(opts.signature, opts.recipient[0], infile=opts.infile, outfile=opts.outfile) else: res = verify_handler(infile=opts.infile, outfile=opts.outfile, basedir=opts.basedir) if res: print >>sys.stderr, "good message from", res else: print >>sys.stderr, 'verification failed' # key sign elif opts.action=='m': ensure_name_specified(opts) ensure_self_specified(opts) sig = keysign_handler(name=opts.name, self=opts.self, basedir=opts.basedir) if sig: print "key signed in", sig else: print >>sys.stderr, 'signature failed'
def dh3_handler(public, exp): secret = nacl.crypto_scalarmult_curve25519(b85decode(exp), b85decode(public)) (sys.stdout.buffer if hasattr(sys.stdout, 'buffer') else sys.stdout).write(b"shared secret " + b85encode(secret) + b'\n') clearmem(secret)
def __str__(self): return b85encode(self.shared)
def _3user(): eA = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES) pA = nacl.crypto_scalarmult_curve25519_base(eA) print("A public: \t%s\nA exp: \t%s" % (b85encode(pA), b85encode(eA))) eB = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES) pB = nacl.crypto_scalarmult_curve25519_base(eB) print("B public: \t%s\nB exp: \t%s" % (b85encode(pB), b85encode(eB))) eC = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES) pC = nacl.crypto_scalarmult_curve25519_base(eC) print("C public: \t%s\nC exp: \t%s" % (b85encode(pC), b85encode(eC))) print() pAB = nacl.crypto_scalarmult_curve25519(eB, pA) print("public AB", b85encode(pAB)) pBA = nacl.crypto_scalarmult_curve25519(eA, pB) print("public BA", b85encode(pBA)) pCA = nacl.crypto_scalarmult_curve25519(eA, pC) print("public CA", b85encode(pCA)) print() key = nacl.crypto_scalarmult_curve25519(eB, pCA) print("key: \t%s" % (b85encode(key))) key = nacl.crypto_scalarmult_curve25519(eC, pBA) print("key: \t%s" % (b85encode(key))) key = nacl.crypto_scalarmult_curve25519(eC, pAB) print("key: \t%s" % (b85encode(key)))
def export_handler(self, basedir=None): keys = publickey.Identity(self, basedir=basedir) pkt = keys.sign(keys.mp + keys.cp + keys.sp + keys.name, master=True) keys.clear() print(b85encode(pkt))
# list secret keys elif opts.action=='L': for i in publickey.get_secret_keys(opts.basedir): print ('valid' if i.valid > datetime.datetime.utcnow() > i.created else 'INVALID'), i.keyid(), i.name # encrypt elif opts.action=='c': if PITCHFORK and opts.PITCHFORK: ensure_recipient_specified(opts) pitchfork.init() res=pitchfork.encrypt(opts.recipient[0], infile=opts.infile, outfile=opts.outfile) if res: print >>sys.stderr, b85encode(res) return if opts.recipient or opts.self: ensure_self_specified(opts) ensure_recipient_specified(opts) encrypt_handler(infile=opts.infile, outfile=opts.outfile, recipient=opts.recipient, self=opts.self, basedir=opts.basedir) # decrypt elif opts.action=='d': if PITCHFORK and opts.PITCHFORK: ensure_recipient_specified(opts) pitchfork.init()
ensure_only_one_recipient(opts) # TODO could try to find out this automatically if non-ambiguous ensure_self_specified(opts) chaining_decrypt_handler(opts.infile, outfile=opts.outfile, recipient=opts.recipient[0], self=opts.self, basedir=opts.basedir) # start ECDH elif opts.action=='ds': ensure_self_specified(opts) ensure_dhparam_specified(opts) ensure_name_specified(opts) sec = mpecdh_start_handler(opts.name, opts.dh_peers, opts.self, opts.infile, opts.outfile, opts.basedir) if sec: print >>sys.stderr, "pushed shared secret, hash", b85encode(nacl.crypto_generichash(sec, outlen=6)) clearmem(sec) sec = None # finish ECDH elif opts.action=='de': ensure_self_specified(opts) ensure_name_specified(opts) sec = mpecdh_end_handler(opts.name, opts.self, opts.infile, opts.outfile, opts.basedir) if sec: print >>sys.stderr, "pushed shared secret, hash", b85encode(nacl.crypto_generichash(sec, outlen=6)) clearmem(sec) sec = None elif opts.action=='R': ensure_size_good(opts)