def test_export_openssh_compressed(self): key_file = load_file("ecc_p256_public_openssh.txt", "rt") pub_key = ECC.import_key(key_file) key_file_compressed = pub_key.export_key(format="OpenSSH", compress=True) assert len(key_file) > len(key_file_compressed) self.assertEquals(pub_key, ECC.import_key(key_file_compressed))
def test_import_private_pem_encrypted(self): for algo in "des3", : # TODO: , "aes128", "aes192", "aes256_gcm": key_file = load_file("ecc_p256_private_enc_%s.pem" % algo) key = ECC.import_key(key_file, "secret") self.assertEqual(ref_private, key) key = ECC.import_key(tostr(key_file), b("secret")) self.assertEqual(ref_private, key)
def test_unsupported_curve(self): # openssl ecparam -name secp224r1 -genkey -noout -out strange-curve.pem -conv_form uncompressed curve = """-----BEGIN EC PRIVATE KEY----- MGgCAQEEHEi7xTHW+5oT8wgpjoEKV7uwMuY8rt2YUZe4j1SgBwYFK4EEACGhPAM6 AATJgfOG+Bnki8robpNM8MtArji43GU9up4B0x9sVhqB+fZP+hXgV9ITN7YX4E/k gVnJp9EBND/tHQ== -----END EC PRIVATE KEY-----""" from Cryptodome.PublicKey.ECC import UnsupportedEccFeature try: ECC.import_key(curve) except UnsupportedEccFeature as uef: assert("1.3.132.0.33" in str(uef)) else: assert(False)
def test_export_public_der_compressed(self): key_file = load_file("ecc_p256_public.der") pub_key = ECC.import_key(key_file) key_file_compressed = pub_key.export_key(format="DER", compress=True) key_file_compressed_ref = load_file("ecc_p256_public_compressed.der") self.assertEqual(key_file_compressed, key_file_compressed_ref)
def add_tests(self, filename): comps = "Cryptodome.SelfTest.Signature.test_vectors.wycheproof".split(".") with open(pycryptodome_filename(comps, filename), "rt") as file_in: tv_tree = json.load(file_in) for group in tv_tree['testGroups']: try: key = ECC.import_key(group['keyPem']) except ValueError: continue hash_name = group['sha'] if hash_name == "SHA-256": hash_module = SHA256 elif hash_name == "SHA-224": hash_module = SHA224 elif hash_name == "SHA-1": hash_module = SHA1 else: assert False assert group['type'] == "ECDSAVer" for test in group['tests']: tv = TestVector() tv.id = test['tcId'] tv.comment = test['comment'] for attr in 'msg', 'sig': setattr(tv, attr, unhexlify(test[attr])) tv.key = key tv.hash_module = hash_module tv.valid = test['result'] != "invalid" tv.warning = test['result'] == "acceptable" self.tv.append(tv)
def test_import_private_pkcs8_encrypted_1(self): key_file = load_file("ecc_p256_private_p8.der") key = ECC._import_der(key_file, "secret") self.assertEqual(ref_private, key) key = ECC.import_key(key_file, "secret") self.assertEqual(ref_private, key)
def test_export_public_pem_compressed(self): key_file = load_file("ecc_p256_public.pem", "rt").strip() pub_key = ECC.import_key(key_file) key_file_compressed = pub_key.export_key(format="PEM", compress=True) key_file_compressed_ref = load_file("ecc_p256_public_compressed.pem", "rt").strip() self.assertEqual(key_file_compressed, key_file_compressed_ref)
def test_import_openssh(self): key_file = load_file("ecc_p256_public_openssh.txt") key = ECC._import_openssh(key_file) self.assertEqual(ref_public, key) key = ECC.import_key(key_file) self.assertEqual(ref_public, key)
def test_import_private_pkcs8_clear(self): key_file = load_file("ecc_p256_private_p8_clear.der") key = ECC._import_der(key_file, None) self.assertEqual(ref_private, key) key = ECC.import_key(key_file) self.assertEqual(ref_private, key)
def test_import_x509_der(self): key_file = load_file("ecc_p256_x509.der") key = ECC._import_der(key_file, None) self.assertEqual(ref_public, key) key = ECC.import_key(key_file) self.assertEqual(ref_public, key)
def test_export_private_pem_encrypted(self): encoded = ref_private._export_private_pem(passphrase=b("secret")) # This should prove that the output is password-protected self.assertRaises(ValueError, ECC.import_key, encoded) assert "EC PRIVATE KEY" in encoded decoded = ECC.import_key(encoded, "secret") self.assertEqual(ref_private, decoded) # --- encoded = ref_private.export_key(format="PEM", passphrase="secret", use_pkcs8=False) decoded = ECC.import_key(encoded, "secret") self.assertEqual(ref_private, decoded)
def test_export_private_pkcs8_and_pem_2(self): # PKCS8 inside PEM with PKCS8 encryption encoded = ref_private._export_private_encrypted_pkcs8_in_clear_pem("secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") # This should prove that the output is password-protected self.assertRaises(ValueError, ECC.import_key, encoded) assert "ENCRYPTED PRIVATE KEY" in encoded decoded = ECC.import_key(encoded, "secret") self.assertEqual(ref_private, decoded) # --- encoded = ref_private.export_key(format="PEM", passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") decoded = ECC.import_key(encoded, "secret") self.assertEqual(ref_private, decoded)
def test_import_public_der(self): key_file = load_file("ecc_p256_public.der") key = ECC._import_subjectPublicKeyInfo(key_file) self.assertEqual(ref_public, key) key = ECC._import_der(key_file, None) self.assertEqual(ref_public, key) key = ECC.import_key(key_file) self.assertEqual(ref_public, key)
def test_compressed_curve(self): # Compressed P-256 curve (Y-point is even) pem1 = """-----BEGIN EC PRIVATE KEY----- MFcCAQEEIHTuc09jC51xXomV6MVCDN+DpAAvSmaJWZPTEHM6D5H1oAoGCCqGSM49 AwEHoSQDIgACWFuGbHe8yJ43rir7PMTE9w8vHz0BSpXHq90Xi7/s+a0= -----END EC PRIVATE KEY-----""" # Compressed P-256 curve (Y-point is odd) pem2 = """-----BEGIN EC PRIVATE KEY----- MFcCAQEEIFggiPN9SQP+FAPTCPp08fRUz7rHp2qNBRcBJ1DXhb3ZoAoGCCqGSM49 AwEHoSQDIgADLpph1trTIlVfa8NJvlMUPyWvL+wP+pW3BJITUL/wj9A= -----END EC PRIVATE KEY-----""" key1 = ECC.import_key(pem1) low16 = int(key1.pointQ.y % 65536) self.assertEqual(low16, 0xA6FC) key2 = ECC.import_key(pem2) low16 = int(key2.pointQ.y % 65536) self.assertEqual(low16, 0x6E57)
def __init__(self, key_locator_name: NonStrictName, key_der: Union[bytes, str]): self.key_locator_name = key_locator_name self.key_der = key_der self.key = ECC.import_key(self.key_der) curve = self.key.curve if curve[-2:] == 'r1' or curve[-2:] == 'v1': self.curve_bit = int(curve[-5:-2]) else: self.curve_bit = int(curve[-3:]) self.key_size = (self.curve_bit * 2 + 7) // 8 self.key_size += self.key_size % 2
def test_export_private_pkcs8_and_pem_2(self): # PKCS8 inside PEM with PKCS8 encryption encoded = ref_private._export_private_encrypted_pkcs8_in_clear_pem( "secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") # This should prove that the output is password-protected self.assertRaises(ValueError, ECC.import_key, encoded) assert "ENCRYPTED PRIVATE KEY" in encoded decoded = ECC.import_key(encoded, "secret") self.assertEqual(ref_private, decoded) # --- encoded = ref_private.export_key( format="PEM", passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") decoded = ECC.import_key(encoded, "secret") self.assertEqual(ref_private, decoded)
def checkTransaction(transaction): validTypes = (0,1) type0Fields = ('ts', 'type', 'from', 'command', 'user') type1Fields = ('ts', 'type', 'from', 'response_to', 'result', 'error') try: # Check if exactly one block entry if len(transaction) != 2: raise Exception('Invalid number of entries.') #Check Signature transactionSig = str(transaction[0]) transactionData = decodeTransaction(transaction) key = ECC.import_key(transactionData[u'from']) transactionHash = SHA256.new(str(transaction[1])) verifier = DSS.new(key, 'fips-186-3') verifier.verify(transactionHash, transactionSig) #Check Fields if ((transactionData[u'type'] == 0) and any(k not in type0Fields for k in transactionData)): raise Exception('Invalid type or fields.') if ((transactionData[u'type'] == 0) and (not all(k in transactionData for k in type0Fields))): raise Exception('Missing fields.') if ((transactionData[u'type'] == 1) and any(k not in type1Fields for k in transactionData)): raise Exception('Invalid type or fields.') if ((transactionData[u'type'] == 1) and (not all(k in transactionData for k in type1Fields))): raise Exception('Missing fields.') #Check 'type' if not(transactionData[u'type'] in validTypes): raise Exception('Invalid Type.') #Check 'ts' if not isinstance(transactionData[u'ts'], (int, long, float)): raise Exception('Invalid Timestamp.') if transactionData[u'type'] == 0: #Check 'command' if not isinstance(transactionData[u'command'], (unicode, str)): raise Exception('Invalid Command.') if transactionData[u'command'] == '': raise Exception('Invalid Command.') #Check 'user' if not isinstance(transactionData[u'user'], (unicode, str)): raise Exception('Invalid User.') if transactionData[u'user'] == '': raise Exception('Invalid User.') if transactionData[u'type'] == 1: #Check 'response_to' if not isinstance(transactionData[u'response_to'], (bson.binary.Binary, str)): raise Exception('Invalid Response Identifier.') #Check 'result' if not isinstance(transactionData[u'result'], (unicode, str)): raise Exception('Invalid Result.') #Check 'error' if not isinstance(transactionData[u'error'], (unicode, str)): raise Exception('Invalid Error.') return True except: return False
def verify_transaction_signature(self, sender_address, signature, transaction): """ Check that the provided signature corresponds to transaction signed by the public key (sender_address) """ public_key = ECC.import_key(binascii.unhexlify(sender_address)) verifier = DSS.new(public_key, 'fips-186-3') h = SHA256.new(str(transaction).encode('utf8')) try: verifier.verify(h, binascii.unhexlify(signature)) return True except ValueError: print('this signature is NOT authentic') return False
def test_export_private_pkcs8_encrypted(self): encoded = ref_private._export_pkcs8(passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") # This should prove that the output is password-protected self.assertRaises(ValueError, ECC._import_pkcs8, encoded, None) decoded = ECC._import_pkcs8(encoded, "secret") self.assertEqual(ref_private, decoded) # --- encoded = ref_private.export_key(format="DER", passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") decoded = ECC.import_key(encoded, "secret") self.assertEqual(ref_private, decoded)
def listKeys(): private = ['Private keys:'] public = ['Public keys:'] for (dirpath, dirnames, filenames) in os.walk(config.KEY_PATH): for filename in filenames: try: with open(dirpath + os.sep + filename) as f: key = ECC.import_key(f.read()) if key.has_private(): private.append('\t' + os.path.splitext(filename)[0]) else: public.append(os.path.splitext('\t' + filename)[0]) except: pass for privkey in private: print privkey for pubkey in public: print pubkey
def __init__(self): super().__init__() self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.currentBalance = 10 self.simulatorBalance = 100 if not os.path.exists('simulatorpublickey.pem'): self.key = ECC.generate(curve='P-256') f = open('simulatorpublickey.pem', 'wt') f.write(key.public_key().export_key(format='PEM')) f.close() f = open('simulatorprivatekey.pem', 'wt') f.write(key.export_key(format='PEM')) f.close() return else: f = open('simulatorprivatekey.pem', 'rt') self.key = ECC.import_key(f.read()) f.close() return
def main(): from Cryptodome.Signature import pss from Cryptodome.Hash import SHA256 from Cryptodome.PublicKey import RSA, ECC import os import logging import sys logging.basicConfig() logger = logging.getLogger(os.path.basename(__file__)) args = get_args(logger) with open(args.master_key, 'rb') as f: master_key = RSA.import_key(f.read()) with open(args.tp_key, 'rb') as f: if args.tp_key_type == 'rsa': tp_key = RSA.import_key(f.read()) tp_key_raw = proc_rsa_key(tp_key) elif args.tp_key_type == 'ecdsa': tp_key = ECC.import_key(f.read()) tp_key_raw = proc_ecdsa_key(tp_key) else: logger.error('Invalid key format') sys.exit(1) h = SHA256.new() h.update(tp_key_raw) md = h.digest() if master_key.has_private(): signer = pss.new(master_key) sig = signer.sign(md) with open(args.uuid + '.crt', 'wb') as f: f.write(sig) f.write(tp_key_raw) else: logger.error('Provided key can\'t be used for signing') sys.exit(1)
def __init__(self): # contains active jobs self.pool_jobs = [] # contains jobs done self.jobs_done = [] # job_id => job self.jobs = {} # user_id => credit self.user_credits = {} # results to be verified self.to_check = [] # job_id => JOB_DONE self.results = {} sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('', 5599)) sock.listen(50) self.sock = sock self.inputs = [sock] self.outputs = [] self.message_queues = {} self.key = None self.public_key = None if not os.path.exists('myprivatekey.pem'): print("creating new ECC private key") self.key = ECC.generate(curve='P-256') f = open('mypublickey.pem', 'wt') f.write(self.key.public_key().export_key(format='PEM')) f = open('myprivatekey.pem', 'wt') f.write(self.key.export_key(format='PEM')) f.close() else: print("reading existing key") f = open('myprivatekey.pem', 'rt') self.key = ECC.import_key(f.read()) f.close() self.public_key = self.key.public_key().export_key(format='PEM') self.user_credits[self.public_key] = 100 print("BlockchainController init end")
def add_tests(self, filename): comps = "Cryptodome.SelfTest.Signature.test_vectors.wycheproof".split( ".") with open(pycryptodome_filename(comps, filename), "rt") as file_in: tv_tree = json.load(file_in) for group in tv_tree['testGroups']: try: key = ECC.import_key(group['keyPem']) except ValueError: continue hash_name = group['sha'] if hash_name == "SHA-512": hash_module = SHA512 elif hash_name == "SHA-384": hash_module = SHA384 elif hash_name == "SHA-256": hash_module = SHA256 elif hash_name == "SHA-224": hash_module = SHA224 elif hash_name == "SHA-1": hash_module = SHA1 else: assert False assert group['type'] == "ECDSAVer" from collections import namedtuple TestVector = namedtuple( 'TestVector', 'id comment msg sig key hash_module valid warning') for test in group['tests']: tv = TestVector(test['tcId'], test['comment'], unhexlify(test['msg']), unhexlify(test['sig']), key, hash_module, test['result'] != "invalid", test['result'] == "acceptable") self.tv.append(tv)
def load(cls, data: bytes) -> ECCPublicKey: """Loads the public key as binary object and returns the Key object. Args: data (bytes, bytearray): The key as bytes object. Returns: ECCPublicKey: An ECC public key. Raises: ValueError: if the key could not be deserialized. """ try: key = ECC.import_key(data) if key.has_private(): raise ValueError("The key is not a private key") return cls(key=key) except ValueError as e: raise ValueError( "Cannot deserialize key. Either Key format is invalid or " "passphrase is missing or incorrect.") from e
def main(): """ Bacon wrapper function """ parser = optparse.OptionParser() parser.add_option('-p', '--public-key', dest='pubkey', help='PEM file containing the ECDSA public key') parser.add_option('-b', '--binhash-file', dest='hash_file', help='Output file containing the SHA256 public key hash') parser.add_option('-d', '--debug', dest='debug', action="store_true", help='Output debugging information') options, _ = parser.parse_args() if not options.pubkey: parser.print_help() print("Must specify public key file", file=sys.stderr) return 1 with open(options.pubkey) as keyfile: key = ECC.import_key(keyfile.read()) sha = hash_pubkey(key, options.debug) print(sha.hexdigest()) if options.hash_file: with open(options.hash_file, 'wb') as hashfile: hashfile.write(sha.digest()) return 0
def add_tests(self, filename): file_in = open( pycryptodome_filename( "Cryptodome.SelfTest.Signature.test_vectors.wycheproof".split( "."), filename), "rt") tv_tree = json.load(file_in) for group in tv_tree['testGroups']: try: key = ECC.import_key(group['keyPem']) except ValueError: continue hash_name = group['sha'] if hash_name == "SHA-256": hash_module = SHA256 elif hash_name == "SHA-224": hash_module = SHA224 elif hash_name == "SHA-1": hash_module = SHA1 else: assert False assert group['type'] == "ECDSAVer" for test in group['tests']: tv = TestVector() tv.id = test['tcId'] tv.comment = test['comment'] for attr in 'msg', 'sig': setattr(tv, attr, unhexlify(test[attr])) tv.key = key tv.hash_module = hash_module tv.valid = test['result'] != "invalid" tv.warning = test['result'] == "acceptable" self.tv.append(tv)
def on_challenge_interest(name: FormalName, param: InterestParam, _app_param: Optional[BinaryStr]): global client_self_signed, testbed_signed, signer, token logging.info("Challenge interest") # extract client public key bits client_pub_key = bytes(testbed_signed.content) # verify verifier = DSS.new(ECC.import_key(client_pub_key), 'fips-186-3', 'der') sha256_hash = SHA256.new() sha256_hash.update(token) try: verifier.verify(sha256_hash, bytes(_app_param)) except ValueError: # proof-of-possesion failed logging.info("Proof-of-possesion failed") content = "proof-of-possesion failed".encode() app.put_data(name, content=content, freshness_period=10000, signer=signer) return # we can derive a new cert for client logging.debug("Proof-of-possesion succeed") client_key_name = client_self_signed.name[:-2] issuer_id = "icear-server" start_time = date.fromtimestamp(time.time()) expire_sec = timedelta(days=30).total_seconds() cert_name, wire = derive_cert(client_key_name, issuer_id, client_pub_key, signer, start_time, expire_sec) logging.info("Newly issused certificate: %s", Name.to_str(cert_name)) app.put_data(name, content=wire, freshness_period=10000, signer=signer)
async def wrapper(name:FormalName, sig:SignaturePtrs) -> bool: nonlocal key_bits sig_info = sig.signature_info covered_part = sig.signature_covered_part sig_value = sig.signature_value_buf if sig_info and sig_info.signature_type == SignatureType.SHA256_WITH_ECDSA: if sig_info.key_locator.name != key_name: return False pub_key = ECC.import_key(key_bits) verifier = DSS.new(pub_key, 'fips-186-3', 'der') sha256_algo = SHA256.new() if not covered_part or not sig_value: ret = False else: for blk in covered_part: sha256_algo.update(blk) try: verifier.verify(sha256_algo, bytes(sig_value)) return True except ValueError: return False SVSyncLogger.debug(f'Digest check {Name.to_str(name)} -> {ret}') return ret return False
def test_import_private_pkcs8_in_pem_clear(self): key_file = load_file("ecc_p256_private_p8_clear.pem") key = ECC.import_key(key_file) self.assertEqual(ref_private, key)
def verify_signature(data, signature, key_data=_PUBLIC_KEY): key = ECC.import_key(key_data) verifier = DSS.new(key, 'fips-186-3') verifier.verify(SHA256.new(data), signature)
async def main(): global local_anchor import_safebag("sec/client.safebag", "1234") # parse again to read prv key into memory request = CertRequest() with open("sec/client.safebag", "r") as safebag: wire = safebag.read() wire = base64.b64decode(wire) wire = parse_and_check_tl(wire, SecurityV2TypeNumber.SAFE_BAG) bag = SafeBag.parse(wire) # attach the testbed-signed certificate request.testbed_signed = bag.certificate_v2 # parse the key bag to obtain private key testbed_signed = CertificateV2Value.parse(bag.certificate_v2) key_bag = bytes(bag.encrypted_key_bag) privateKey = serialization.load_der_private_key(key_bag, password=b'1234', backend=default_backend()) client_prv_key = privateKey.private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption()) # parse trust anchor and self-assigns a name, then create self-signed certificate with open("sec/client.anchor", "r") as anchor: wire = anchor.read() wire = base64.b64decode(wire) local_anchor = parse_certificate(wire) # self-assign a name and create corresponding key pair client_name = local_anchor.name[:-4] + [testbed_signed.name[-5]] client_identity = app.keychain.touch_identity(client_name) # attach newly generated self-assigned certificate cert = client_identity.default_key().default_cert().data cert = parse_certificate(cert) request.self_signed = cert.encode() try: # express the first interest to fetch a token/secret code timestamp = ndn.utils.timestamp() name = Name.from_str('/edge/_ca/new-cert') + [Component.from_timestamp(timestamp)] logging.info(f'Sending Interest {Name.to_str(name)}, {InterestParam(must_be_fresh=True, lifetime=6000)}') data_name, meta_info, content = await app.express_interest( name, app_param=request.encode(), must_be_fresh=True, can_be_prefix=False, lifetime=6000, identity=client_identity, validator=verify_ecdsa_signature) # sign it use the private key, to prove the certificate possesion h = SHA256.new() h.update(bytes(content)) pk = ECC.import_key(client_prv_key) signature = DSS.new(pk, 'fips-186-3', 'der').sign(h) logging.info(f'Getting Data {Name.to_str(name)}, begin signing the token {bytes(content)}') # express the second interest to fetch the issued certificate name = Name.from_str('/edge/_ca/challenge') + [Component.from_timestamp(timestamp)] logging.info(f'Sending Interest {Name.to_str(name)}, {InterestParam(must_be_fresh=True, lifetime=6000)}') data_name, meta_info, content = await app.express_interest( name, app_param=signature, must_be_fresh=True, can_be_prefix=False, lifetime=6000, identity=client_identity, validator=verify_ecdsa_signature) # parse the issued certificate and install issued_cert = parse_certificate(content) logging.info("Issued certificate: %s", Name.to_str(issued_cert.name)) app.keychain.import_cert(Name.to_bytes(issued_cert.name[:-2]), Name.to_bytes(issued_cert.name), bytes(content)) except InterestNack as e: print(f'Nacked with reason={e.reason}') except InterestTimeout: print(f'Timeout') except InterestCanceled: print(f'Canceled') except ValidationFailure: print(f'Data failed to validate') app.shutdown()
from Cryptodome.PublicKey import ECC key = None if not os.path.exists('myprivatekey.pem'): print("creating new ECC private key") key = ECC.generate(curve='P-256') f = open('mypublickey.pem', 'wt') f.write(key.public_key().export_key(format='PEM')) f.close() f = open('myprivatekey.pem', 'wt') f.write(key.export_key(format='PEM')) f.close() else: print("reading existing key") f = open('myprivatekey.pem', 'rt') key = ECC.import_key(f.read()) f.close() h = SHA256.new("message".encode()) signer = DSS.new(key, 'fips-186-3') signature = signer.sign(h) h = SHA256.new("message".encode()) verifier = DSS.new(key.public_key(), 'fips-186-3') try: verifier.verify(h, signature) print("The message is authentic.") except ValueError: print("The message is not authentic.")
def test_import_private_pem(self): key_file = load_file("ecc_p256_private.pem") key = ECC.import_key(key_file) self.assertEqual(ref_private, key)
def test_import_x509_pem(self): key_file = load_file("ecc_p256_x509.pem") key = ECC.import_key(key_file) self.assertEqual(ref_public, key)
def test_import_private_pem_with_ecparams(self): if sys.version_info[:2] == (2, 6): return key_file = load_file("ecc_p256_private_ecparams.pem") key = ECC.import_key(key_file)
def test_import_public_pem(self): key_file = load_file("ecc_p521_public.pem") key = ECC.import_key(key_file) self.assertEqual(self.ref_public, key)
def _verify(cls, pub_key_bits, sig_ptrs) -> bool: if sig_ptrs.signature_info.signature_type != SignatureType.SHA256_WITH_ECDSA: return False pub_key = ECC.import_key(bytes(pub_key_bits)) return verify_ecdsa(pub_key, sig_ptrs)
def Ope_func(m_dict): curve = sslcrypto.ecc.get_curve('prime256v1') KeyTrans = key_type_transform.KeyTrans() # 注意示例化!!! # ************************UDP服务器端编程********************************* s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('127.0.0.1', 9999)) # 绑定端口 data, addr = s.recvfrom(4096) s.close() m_UE_AMF = pickle.loads(data) # 收到消息后,反序列化得到 {'ciphertext': ciphertext, 'signature': signature} signature_UE = m_UE_AMF['signature'] ciphertext_UE = m_UE_AMF['ciphertext'] print("***AMF***收到的UE发送的消息<UText, E, σ>") start_reg = time.clock() # *****************************AMF读取用户的公钥进行验签*********************************** public_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\UE_publickey.pem').read()) x = public_key_raw.pointQ.x.__int__() y = public_key_raw.pointQ.y.__int__() pk_UE = KeyTrans.b_public_key(x, y) s = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 s.update(ciphertext_UE) cipher_h = s.hexdigest() b_cipher_h_UE = bytes(cipher_h, encoding='utf-8') # 这里注意把 16进制的密文摘要转换为字节串,进行处理utf-8编码 print('***AMF***验证UE的签名成功!!!') if curve.verify(signature_UE, b_cipher_h_UE, pk_UE) else print('***AMF***验证UE的签名失败!!!') # ************************************在Operator核心网内AMF把ciphertext_UE消息转交给SMF处理******************************************************* # ***************************SMF利用Ope的私钥开始解密,获取用户注册信息CH_UE,ID_UE,ID_A3VI**************************************** print('---2--- AMF >> SMF 发送消息<UText, E>') print('服务注册阶段消息<UText, E>字节数为:', len(ciphertext_UE)) private_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\Ope_privatekey.pem').read()).d.__int__() sk = KeyTrans.b_private_key(private_key_raw) # 注意!!!这是Ope的私钥 b_message_UE = curve.decrypt(ciphertext_UE, sk, algo='aes-256-ofb') message_UE = pickle.loads(b_message_UE) # 这里获得UE的注册信息 {'CH_UE': CH_UE.CH(), 'N': N, 'ID_UE': ID_UE, 'ID_A3VI': ID_A3VI} print('***SMF***解密UText为:', message_UE) # print(message_UE) # print(type(message_UE)) # *****************************************SMF把注册消息转发给AUSF处理******************************************************** print('---3--- SMF >> AUSF 发送消息<CH_UE, N, ID_UE, ID_A3VI>') print('服务注册阶段消息<CH_UE, N, ID_UE, ID_A3VI>字节数为:', len(message_UE['CH_UE']) + len(int_to_bytes(message_UE['N'], 32)) + len(message_UE['ID_UE'])+len(message_UE['ID_A3VI'])) TXID_ST = b'8b60004928090023bef4292ed4e0e414a9f1eaa2d734d4b34beb5c6b2f33bb59' T_Exp = time.clock() print('AUSF需要备份存储的TXID数据量为:', len(TXID_ST)+len(message_UE['ID_UE'])+len(message_UE['ID_A3VI'])+T_Exp.__int__().bit_length()/8, 'bytes') # *************************读取Ope的公私钥,并混进环成员中,这里的公私钥形式为(x,y) d ********************************* # public_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\Ope_publickey.pem').read()) # x = public_key_raw.pointQ.x.__int__() # y = public_key_raw.pointQ.y.__int__() # pk_Ope = (x, y) # # private_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\Ope_privatekey.pem').read()).d.__int__() # sk_Ope = private_key_raw # 注意!!!这是Ope的私钥 """ 这里Ope把自己的公私钥混进环成员这里,在测试的时候,发现aosring的算法是基于secp256k1 (bitcoin)的,而我们其余的代码都是 基于secp256r1的椭圆曲线,所以这里暂时随机生成密钥,用于环签名。 """ # ******************************************************************************************* n = 30 # keys = Ring_Group.generate_RG_with_input_key(n, pk_Ope, sk_Ope) # 我们这里随机生成一些公私钥,假装找了一些其他的Ope成员形成环 keys = aosring_randkeys(n) CH_N = {'CH_UE': message_UE['CH_UE'], 'N': message_UE['N']} b_CH_N = pickle.dumps(CH_N) s = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 s.update(b_CH_N) b_CH_N_h_0x = s.hexdigest() b_CH_N_h = bytes(b_CH_N_h_0x, encoding='utf') msg = bytes_to_int(b_CH_N_h) # AUSF开始进行环签名,生成一个半成品票据PST PST_all = aosring_sign(*keys, message=msg) PST = (PST_all[1], PST_all[2]) # 这里是签名的有效部分tees, cees[-1] 形式为 ((x, y), z) print('***AUSF***生成半成品票据PST') # AUSF把半成品票据和用户注册信息打包后,加密并签名发送给A3VI CH_UE||N||RG||PST # message_AUSF = {'CH_UE': message_UE['CH_UE'], 'N': message_UE['N'], 'RG_Ope': keys, 'PST': PST} # 这里测通信开销,我们应该只发送证书序列号就可以了,每个整数序列 cert_ID = 0x0546fe1823f7e1941da39fce14c46173 cert = [] for _ in range(n): cert.append(cert_ID) message_AUSF = {'CH_UE': message_UE['CH_UE'], 'N': message_UE['N'], 'RG_Ope': cert, 'PST': PST} b_message_AUSF = pickle.dumps(message_AUSF) # mmmm_AUSF = [message_UE['CH_UE'], message_UE['N'], keys, PST] # b_mmmm_AUSF = pickle.dumps(mmmm_AUSF) # print('<CText, E2, β>字节数字典%s vs 列表%s 对比:', len(b_message_AUSF), len(b_mmmm_AUSF)) # 开始加密和签名 public_key_raw1 = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\A3VI_publickey.pem').read()) x1 = public_key_raw1.pointQ.x.__int__() y1 = public_key_raw1.pointQ.y.__int__() pk_A3VI = KeyTrans.b_public_key(x1, y1) ciphertext = curve.encrypt(b_message_AUSF, pk_A3VI, algo='aes-256-ofb') # 这里要用AUSF的公钥来加密 s1 = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 s1.update(ciphertext) cipher_h = s1.hexdigest() b_cipher_h = bytes(cipher_h, encoding='utf-8') # 这里注意把 16进制的密文摘要转换为字节串,进行处理utf-8编码 signature = curve.sign(b_cipher_h, sk) # 注意!!!这是Ope的私钥 # print("Ope发送的签名为:", signature) m_AUSF_A3VI = {'ciphertext': ciphertext, 'signature': signature} # 这是AUSF需要发送的消息密文和签名 b_m_AUSF_A3VI = pickle.dumps(m_AUSF_A3VI) # 消息序列化为字节串 end_reg = time.clock() print('Ope端服务注册阶段计算开销为:', (end_reg-start_reg)*1000, 'ms') m_dict['Ope_Reg'] = (end_reg-start_reg)*1000 # gol.set_value('Ope_Reg', (end_reg-start_reg)*1000) # **********************UDP客户端编程*************************************** print('---4--- AUSF >>>> A3VI 发送消息<CText, E2, β>') print('服务注册阶段消息<CText, E2, β>字节数为:', len(ciphertext)+len(signature)) m_dict['2'] = len(ciphertext)+len(signature) m = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) m.sendto(b_m_AUSF_A3VI, ('127.0.0.1', 12345)) m.close()
def test_import_private_pkcs8_encrypted_2(self): key_file = load_file("ecc_p256_private_p8.pem") key = ECC.import_key(key_file, "secret") self.assertEqual(ref_private, key)
logging.basicConfig(format='%(message)s', level=logging.INFO, stream=sys.stderr) log = logging.getLogger() BASE64_STANDARD = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' BASE64_CUSTOM = b'HJIA/CB+FGKLNOP3RSlUVWXYZfbcdeaghi5kmn0pqrstuvwx89o12467MEDyzQjT' ECC_KEY = '''-----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8yCG2yBN8HM3tfsYsMCvgLvz+/FKwDvG AB8j7xxMBlSjj6YZfEFX6wu8f0GhWHlwDcOhOBxe4nrRKfu2VUHVjsfHPh7ztGdj 01D1W1/RwFa4OIfbtUTX4Th5PmMrAy7I -----END PUBLIC KEY----- ''' verifier = DSS.new(ECC.import_key(ECC_KEY), 'fips-186-3') def derive_key(rounds, data): h = SHA256.new() for _ in range(rounds): h.update(data) data = h.digest() return data def decrypt_data(data): if data is None: return None key = derive_key(128, data[:0x20])[:0x20]
def UE_func(m_dict): print( '-----------------------------------------切片服务注册过程-----------------------------------------------' ) start_reg = time.clock() # ***************************开始计算变色龙哈希值******************************* ChameleonHash = ChameleonHash_ECC.ChameleonHash() # 实例化对象,这一步注意不可少!!! KeyTrans = key_type_transform.KeyTrans() order = ChameleonHash.order() m0 = random.randint(1, order - 1) # 这里m0 r0 是用户初始的两个变色龙哈希输入值 r0 = random.randint(1, order - 1) # 从(1,order)中随机选择两个数m0,r0作为我们变色龙哈希函数的初始输入 CH_UE = ChameleonHash.Compute_CH(m0, r0) # print('计算好的哈希值和陷门', CH_UE.CH()) # CH(m0,r0) = mP + rY # print('陷门为:', CH_UE.trapdoor()) #陷门信息为(k,x) N = random.getrandbits(256) # 获取256位随机位(二进制)的整数作为本次会话的会话号 ID_UE = b'123456789abcdef' # 用于模拟15位的SUPI / IMSI ID_A3VI = b'987654321abcdef' # 类似的给A3VI分配一个ID号 message_UE = { 'CH_UE': CH_UE.CH(), 'N': N, 'ID_UE': ID_UE, 'ID_A3VI': ID_A3VI } # 这是UE需要发送的消息明文 b_message_UE = pickle.dumps(message_UE) # 消息序列化为字节串 # print(b_message_UE) # print(type(b_message_UE)) # *************************读取UE的私钥和公钥************************************* private_key_raw = ECC.import_key( open(r'D:\PythonProject\FUIH\ECC_file_keys\UE_privatekey.pem').read() ).d.__int__() sk = KeyTrans.b_private_key(private_key_raw) # *************************开始加密和签名************************************ # 读取Ope的公钥 public_key_raw_Ope = ECC.import_key( open(r'D:\PythonProject\FUIH\ECC_file_keys\Ope_publickey.pem').read()) x1 = public_key_raw_Ope.pointQ.x.__int__() y1 = public_key_raw_Ope.pointQ.y.__int__() pk_Ope = KeyTrans.b_public_key(x1, y1) curve = sslcrypto.ecc.get_curve('prime256v1') ciphertext = curve.encrypt(b_message_UE, pk_Ope, algo='aes-256-ofb') # 这里要用Ope的公钥来加密 h = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 h.update(ciphertext) cipher_h = h.hexdigest() b_cipher_h = bytes(cipher_h, encoding='utf-8') # 这里注意把 16进制的密文摘要转换为字节串,进行处理utf-8编码 signature = curve.sign(b_cipher_h, sk) m_UE_AMF = { 'ciphertext': ciphertext, 'signature': signature } # 这是UE需要发送的消息密文和签名 print('服务注册阶段消息<UText, E1, σ>字节数为:', len(ciphertext) + len(signature)) m_dict['1'] = len(ciphertext) + len(signature) b_m_UE_AMF = pickle.dumps(m_UE_AMF) # 消息序列化为字节串 # print('序列化后的消息<UText, E1, σ>字节数为:', len(b_m_UE_AMF)) end_reg = time.clock() print('UE端服务注册阶段计算开销:', (end_reg - start_reg) * 1000, 'ms') m_dict['UE_Reg'] = (end_reg - start_reg) * 1000 # print(m_UE_AMF) # print(b_m_UE_AMF) # **********************UDP客户端编程【发送给AMF消息进行注册】*************************************** s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto(b_m_UE_AMF, ('127.0.0.1', 9999)) # s.close() 发送完ACK_UE再关闭 print('---1--- UE >>>> AMF 发送消息<UText, E1, σ>') # print('发送消息成功,消息内容为:', b_m_UE_AMF) # ************************UDP服务器端编程********************************* v = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) v.bind(('127.0.0.1', 12347)) # 绑定端口 # print('007data:', pickle.loads(data)) # v.close() 收到密钥协商材料后再close # TXID_ST = b'8b60004928090023bef4292ed4e0e414a9f1eaa2d734d4b34beb5c6b2f33bb59' data_A3VI_UE, addr = v.recvfrom(4096) # 接收A3VI返回的注册后的确认消息<TXID_UE, T_Exp> m_A3VI_UE = pickle.loads(data_A3VI_UE) # print('007UE收到的注册确认消息TXID_UE:', m_A3VI_UE) TXID_ST = m_A3VI_UE['TXID_ST'] # end_reg = time.clock() # print('整个切片服务注册阶段计算开销为:', (end_reg-start_reg) * 1000, 'ms') # **********************UDP客户端编程【发送给EC消息进行认证】*************************************** start_auth = time.clock() SST = 0b10110001 w = {'SST': SST, 'ID_A3VI': ID_A3VI} b_w = pickle.dumps(w) # 这里生成 Hidden_Alloewed_S_NSSAI k = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 k.update(b_w) w_h = k.hexdigest() b_w_h = bytes(w_h, encoding='utf-8') # 这里注意把 16进制的密文摘要转换为字节串,进行处理utf-8编码 Hidden_Allowed_S_NSSAI = b_w_h print( '+++++++++++++++++++++++++++++++++++++++++++Inter-slice handover Authenticaion Phase++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' ) PID_UE = b'123456789abcdef12345' # 用户自己随机选择一个20位的假名 alpha = random.randint(1, order - 1) # 用于计算变色龙哈希碰撞 beta = random.randint(1, order - 1) Y = ChameleonHash.get_Y() A_UE = Y.pointQ.__mul__(alpha) # A_UE = alpha * Y B_UE = Y.pointQ.__mul__(beta) # B_UE = beta * Y T_Curr = time.clock() m = {'PID_UE': PID_UE, 'A_UE': A_UE.xy, 'B_UE': B_UE.xy, "T_Curr": T_Curr} b_m = pickle.dumps(m) h = hashlib.sha3_256() h.update(b_m) m_h = h.hexdigest() b_m_h = bytes(m_h, encoding='utf-8') gamma = bytes_to_int(b_m_h) k = CH_UE.trapdoor()[0] x = CH_UE.trapdoor()[1] r1 = alpha * gamma m1 = (k - r1 * x + order) % order end_auth = time.clock() print('UE端在服务认证阶段的计算开销为:', (end_auth - start_auth) * 1000, 'ms') m_dict['UE_Auth'] = (end_auth - start_auth) * 1000 # # TXID_ST = b'8b60004928090023bef4292ed4e0e414a9f1eaa2d734d4b34beb5c6b2f33bb59' # # data_A3VI_UE, addr = v.recvfrom(4096) # 接收A3VI返回的注册后的确认消息<TXID_UE, T_Exp> # # m_A3VI_UE = pickle.loads(data_A3VI_UE) # # print('007UE收到的注册确认消息TXID_UE:', m_A3VI_UE) # TXID_ST = m_A3VI_UE['TXID_ST'] # end_reg = time.clock() # print('整个切片服务注册阶段计算开销为:', (end_reg-start_reg) * 1000, 'ms') data, addr = v.recvfrom(4096) m_UE_EC = { 'Hidden_Allowed_S_NSSAI': Hidden_Allowed_S_NSSAI, 'PID_UE': PID_UE, 'A_UE': A_UE.xy, 'B_UE': B_UE.xy, 'm_UE': m1, 'T_Curr': T_Curr, 'TXID_ST': TXID_ST } b_m_UE_EC = pickle.dumps(m_UE_EC) print( '+++1+++ UE >>>> EC 发送认证消息<Hidden_Allowed_S_NSSAI, PID_UE, A_UE, B_UE, m_UE, T_Curr, TXID_ST>' ) # print('服务认证阶段消息<Hidden_Allowed_S_NSSAI, PID_UE, A_UE, B_UE, m_UE, T_Curr, TXID_ST>字节数:', len(Hidden_Allowed_S_NSSAI) + # len(PID_UE) + 64 + 64 +len(int_to_bytes(m1, 5))+len(int_to_bytes(T_Curr.__int__(), 5))+len(TXID_ST)) print( '服务认证阶段消息<Hidden_Allowed_S_NSSAI, PID_UE, A_UE, B_UE, m_UE, T_Curr, TXID_ST>字节数:', len(Hidden_Allowed_S_NSSAI) + len(PID_UE) + 64 + 64 + m1.bit_length() / 8 + T_Curr.__int__().bit_length() / 8 + len(TXID_ST)) m_dict['4'] = len(Hidden_Allowed_S_NSSAI) + len( PID_UE) + 64 + 64 + m1.bit_length() / 8 + T_Curr.__int__().bit_length( ) / 8 + len(TXID_ST) if data == b'start': l = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) l.sendto(b_m_UE_EC, ('127.0.0.1', 12346)) l.close() ack_data, addr = v.recvfrom(1024) DoKeyAgreement = pickle.loads(ack_data) if DoKeyAgreement: print('***UE***收到密钥协商提示为True。') else: print('***UE***收到密钥协商提示为False。') # end_auth =time.clock() # print('整个服务认证阶段计算开销为:', (end_auth - start_auth) * 1000, 'ms') # print('发送消息成功,消息内容为:', b_m_UE_EC) # 接收A3VI密钥协商材料,并计算协商材料K值 agree_data, addr = v.recvfrom(4096) A3VI_UE = pickle.loads(agree_data) # {'A_A3VI': A_A3VI, 'B_A3VI': B_A3VI} print('***UE***接收到的A3VI的密钥协商材料为:', A3VI_UE) start_agree = time.clock() x_A = A3VI_UE['A_A3VI'][0] y_A = A3VI_UE['A_A3VI'][1] A_A3VI = ECC.EccPoint(x_A, y_A) x_B = A3VI_UE['B_A3VI'][0] y_B = A3VI_UE['B_A3VI'][1] B_A3VI = ECC.EccPoint(x_B, y_B) x_UE = ChameleonHash.get_x().__int__() K_UE = (A_A3VI + B_A3VI).__mul__(x_UE * (alpha + beta)) print('***UE***计算出的密钥协商材料K为:', K_UE.xy) # 开始计算协商密钥 hash_m = [PID_UE, m1, K_UE.xy] # b_hash_m = pickle.dumps(hash_m) # print('哈希前的长度', len(b_hash_m)) # h.update(b_hash_m[0:16]) # SK_A3VI = h.hexdigest() # print(b_hash_m) b_hash_m = bytes_to_int(pickle.dumps(hash_m)) SK_A3VI = hash(b_hash_m) end_agree = time.clock() print('UE端密钥协商阶段计算开销为:', (end_agree - start_agree) * 1000, 'ms') m_dict['UE_KA'] = (end_agree - start_agree) * 1000 # SK = hash(b_hash_m) print('***UE***计算出的会话密钥[Int类型]为:', SK_A3VI) # print(SK) # 【通过EC】发送ACK_UE消息给A3VI hash_m1 = [K_UE.xy, SK_A3VI] ACK = hash(bytes_to_int(pickle.dumps(hash_m1))) b_ACK = pickle.dumps(ACK) s.sendto(b_ACK, ('127.0.0.1', 12345)) s.close() print('+++4+++ UE >>>> A3VI 发送消息ACK') # print(type(ACK)) print('密钥协商阶段消息<ACK>字节数为:', ACK.bit_length() / 8) m_dict['7'] = ACK.bit_length() / 8 print('++++++++++++++++++++UE端密钥协商完成!!!++++++++++++++++++++++++')
def main(): """ Bacon wrapper function """ global LOG LOG = logging.getLogger(sys.argv[0]) LOG.addHandler(logging.StreamHandler()) parser = optparse.OptionParser() parser.add_option('-k', '--key-file', dest='key_file', help='PEM file containing the ECDSA key') parser.add_option('-p', '--passphrase', dest='keypass', help='Passphrase for private key, if applicable') parser.add_option('-v', '--verbose', dest='verbose', action="store_true", help='Output informative messages') parser.add_option('-d', '--debug', dest='debug', action="store_true", help='Output debugging information') parser.add_option('-e', '--verify', dest='verify_file', help='Verify signature of STM32 image') parser.add_option('-s', '--sign', dest='sign', help='Sign a STM32 image') parser.add_option('-o', '--output', dest='outfile', help='Passphrase for private key, if applicable') options, _ = parser.parse_args() if not options.key_file: parser.print_help() LOG.error("Must specify a key file") return 1 if options.debug: LOG.setLevel(logging.DEBUG) elif options.verbose: LOG.setLevel('INFO') with open(options.key_file) as keyfile: key = ECC.import_key(keyfile.read(), passphrase=options.keypass) if options.sign: if not key.has_private(): LOG.error('The private key is required for signing') return 1 with open(options.sign, 'rb') as image: data = bytearray(image.read()) sign_image(data, key) if options.outfile: with open(options.outfile, 'wb') as out: out.write(data) if options.verify_file: try: stm32_file = open(options.verify_file, 'rb') verify_signature(stm32_file.read(), key) return 0 except OSError as err: LOG.error("Can't open %s", options.verify_file) return err.errno return 0