def verify_sig(verify_key: str, sig: str, msg: bytes) -> bool: vk = VerifyingKey(vk_s=verify_key, prefix='', encoding='hex') try: vk.verify(sig=sig, msg=msg, prefix='', encoding='hex') except Exception as e: return False return True
class Proto(ubirch.Protocol): UUID_DEV = UUID(hex="9d3c78ff-22f3-4441-a5d1-85c636d486ff") PUB_DEV = VerifyingKey("a2403b92bc9add365b3cd12ff120d020647f84ea6983f98bc4c87e0f4be8cd66", encoding='hex') UUID_DEMO = UUID(hex="07104235-1892-4020-9042-00003c94b60b") PUB_DEMO = VerifyingKey("39ff77632b034d0eba6d219c2ff192e9f24916c9a02672acb49fd05118aad251", encoding='hex') UUID_PROD = UUID(hex="10b2e1a4-56b3-4fff-9ada-cc8c20f93016") PUB_PROD = VerifyingKey("ef8048ad06c0285af0177009381830c46cec025d01d86085e75a4f0041c2e690", encoding='hex') def __init__(self, key_store: ubirch.KeyStore, uuid: UUID) -> None: super().__init__() self.__ks = key_store # check if the device already has keys or generate a new pair if not keystore.exists_signing_key(uuid): keystore.create_ed25519_keypair(uuid) # check if the keystore already has the backend key for verification or insert verifying key if not self.__ks.exists_verifying_key(self.UUID_DEV): self.__ks.insert_ed25519_verifying_key(self.UUID_DEV, self.PUB_DEV) if not self.__ks.exists_verifying_key(self.UUID_DEMO): self.__ks.insert_ed25519_verifying_key(self.UUID_DEMO, self.PUB_DEMO) if not self.__ks.exists_verifying_key(self.UUID_PROD): self.__ks.insert_ed25519_verifying_key(self.UUID_PROD, self.PUB_PROD) # load last signature for device self.load(uuid) logger.info("ubirch-protocol: device id: {}".format(uuid)) def persist(self, uuid: UUID): signatures = self.get_saved_signatures() with open(uuid.hex + ".sig", "wb") as f: pickle.dump(signatures, f) def load(self, uuid: UUID): try: with open(uuid.hex + ".sig", "rb") as f: signatures = pickle.load(f) logger.info("loaded {} known signatures".format(len(signatures))) self.set_saved_signatures(signatures) except FileNotFoundError: logger.warning("no existing saved signatures") pass def _sign(self, uuid: UUID, message: bytes) -> bytes: return self.__ks.find_signing_key(uuid).sign(message) def _verify(self, uuid: UUID, message: bytes, signature: bytes): return self.__ks.find_verifying_key(uuid).verify(signature, message)
def address_from_pubkey(pub: ed25519.VerifyingKey): if isinstance(pub, ed25519.VerifyingKey): pub = pub.to_bytes() elif isinstance(pub, str): pub = from_base64(pub) key_hash = sha256(pub).digest() enc = base58.b58encode_check(key_hash[:8]) return enc.decode("ascii")
def get_certificate(self, uuid: UUID) -> dict or None: if not uuid.hex in self._ks.certs: return None cert = self._ks.certs[uuid.hex] vk = VerifyingKey(cert.cert) created = datetime.fromtimestamp(cert.timestamp) not_before = datetime.fromtimestamp(cert.timestamp) # TODO fix handling of key validity not_after = created + timedelta(days=365) return { "algorithm": 'ECC_ED25519', "created": int(created.timestamp()), "hwDeviceId": uuid.bytes, "pubKey": vk.to_bytes(), "pubKeyId": vk.to_bytes(), "validNotAfter": int(not_after.timestamp()), "validNotBefore": int(not_before.timestamp()) }
def insert_ed25519_keypair(self, uuid: UUID, vk: VerifyingKey, sk: SigningKey) -> (VerifyingKey, SigningKey): """Store an existing ED25519 key pair in the key store.""" if uuid.hex in self._ks.entries or uuid.hex in self._ks.certs: raise Exception("uuid '{}' already exists in keystore".format( uuid.hex)) self.insert_ed25519_verifying_key(uuid, vk) self.insert_ed25519_signing_key(uuid, sk) self._ks.save(self._ks_file, self._ks_password) logger.info("inserted new key pair for {}: {}".format( uuid.hex, bytes.decode(vk.to_ascii(encoding='hex')))) return vk, sk
def __init__(self, private_key, public_key): """ Constructor for EdDSA key pair. If only private key available then public key will be generate from private. Args: private_key (bytes): ed25519 private key public_key (bytes, optional): ed25519 public key """ super(EdDSA, self).__init__() if private_key and public_key: self._private_key = private_key self._public_key = public_key self._private_key_obj = SigningKey(self._private_key) self._public_key_obj = VerifyingKey(self._public_key) elif private_key: self._private_key = private_key self._private_key_obj = SigningKey(self._private_key) self._public_key_obj = self._private_key_obj.get_verifying_key() self._public_key = self._public_key_obj.to_bytes() elif public_key: self._public_key = public_key self._public_key_obj = VerifyingKey(self._public_key) if self._private_key: self._private_key_hex = self._private_key.hex() self._public_key_hex = self._public_key.hex() self._address = generate_address( _family_name=RemmeFamilyName.PUBLIC_KEY.value, _public_key_to=self._public_key, ) self._key_type = KeyType.EdDSA
class Proto(ubirch.Protocol): UUID_PROD = UUID(hex="10b2e1a4-56b3-4fff-9ada-cc8c20f93016") PUB_PROD = VerifyingKey( "ef8048ad06c0285af0177009381830c46cec025d01d86085e75a4f0041c2e690", encoding='hex') def __init__(self, key_store: ubirch.KeyStore, uuid: UUID) -> None: super().__init__() self.__ks = key_store # check if the device already has keys or generate a new pair if not keystore.exists_signing_key(uuid): keystore.create_ed25519_keypair(uuid) # check if the keystore already has the backend key for verification or insert verifying key if not self.__ks.exists_verifying_key(self.UUID_PROD): self.__ks.insert_ed25519_verifying_key(self.UUID_PROD, self.PUB_PROD) # load last signature for device self.load(uuid) logger.info("ubirch-protocol: device id: {}".format(uuid)) def persist(self, uuid: UUID): signatures = self.get_saved_signatures() with open(uuid.hex + ".sig", "wb") as f: pickle.dump(signatures, f) def load(self, uuid: UUID): try: with open(uuid.hex + ".sig", "rb") as f: signatures = pickle.load(f) logger.info("loaded {} known signatures".format( len(signatures))) self.set_saved_signatures(signatures) except FileNotFoundError: logger.warning("no existing saved signatures") pass def _sign(self, uuid: UUID, message: bytes) -> bytes: return self.__ks.find_signing_key(uuid).sign(message) def _verify(self, uuid: UUID, message: bytes, signature: bytes): return self.__ks.find_verifying_key(uuid).verify(signature, message)
class EdDSA(KeyDto, IRemmeKeys): """ EdDSA (ed25519) class implementation. References:: - https://github.com/warner/python-ed25519 """ def __init__(self, private_key, public_key): """ Constructor for EdDSA key pair. If only private key available then public key will be generate from private. Args: private_key (bytes): ed25519 private key public_key (bytes, optional): ed25519 public key """ super(EdDSA, self).__init__() if private_key and public_key: self._private_key = private_key self._public_key = public_key self._private_key_obj = SigningKey(self._private_key) self._public_key_obj = VerifyingKey(self._public_key) elif private_key: self._private_key = private_key self._private_key_obj = SigningKey(self._private_key) self._public_key_obj = self._private_key_obj.get_verifying_key() self._public_key = self._public_key_obj.to_bytes() elif public_key: self._public_key = public_key self._public_key_obj = VerifyingKey(self._public_key) if self._private_key: self._private_key_hex = self._private_key.hex() self._public_key_hex = self._public_key.hex() self._address = generate_address( _family_name=RemmeFamilyName.PUBLIC_KEY.value, _public_key_to=self._public_key, ) self._key_type = KeyType.EdDSA @staticmethod def generate_key_pair(seed=None): """ Generate public and private key pair. Args: seed (bytes, optional): seed Returns: Generated key pair in bytes. """ if seed: private_key_obj, public_key_obj = ed25519.SigningKey(seed), ed25519.VerifyingKey(seed) return private_key_obj.to_bytes(), public_key_obj.to_bytes() private_key_obj, public_key_obj = ed25519.create_keypair(entropy=os.urandom) return private_key_obj.to_bytes(), public_key_obj.to_bytes() @staticmethod def get_address_from_public_key(public_key): """ Get address from public key. Args: public_key (bytes): public key in bytes Returns: Address in blockchain generated from public key string. """ return generate_address(RemmeFamilyName.PUBLIC_KEY.value, public_key) def sign(self, data, rsa_signature_padding=None): """ Sign provided data with selected key implementation. Args: data (str): data string which will be signed rsa_signature_padding (RsaSignaturePadding, optional): not used in EdDSA Returns: Hex string of signature. """ if self._private_key_obj is None: raise Exception('Private key is not provided!') if isinstance(data, str): data = utf8_to_bytes(data) return self._private_key_obj.sign(msg=hashlib.sha256(data).digest()) def verify(self, data, signature, rsa_signature_padding=None): """ Verify signature for selected key implementation. Args: data (str): data string which will be verified signature (str): hex string of signature rsa_signature_padding (RsaSignaturePadding, optional): not used in EdDSA Returns: Boolean ``True`` if signature is correct, or ``False`` if invalid. """ if isinstance(data, str): data = utf8_to_bytes(data) try: self._public_key_obj.verify( sig=signature, msg=hashlib.sha256(data).digest(), ) return True except ed25519.BadSignatureError: return False
import hashlib from uuid import UUID from ed25519 import VerifyingKey import ubirch from ubirch.ubirch_protocol import SIGNED remote_uuid = UUID(hex="6eac4d0b-16e6-4508-8c46-22e7451ea5a1") remote_vk = VerifyingKey( "b12a906051f102881bbb487ee8264aa05d8d0fcc51218f2a47f562ceb9b0d068", encoding='hex') # a random signed ubirch-protocol message keystore = ubirch.KeyStore("demo-device.jks", "keystore") keystore.insert_ed25519_verifying_key(remote_uuid, remote_vk) class ProtocolImpl(ubirch.Protocol): def _verify(self, uuid: UUID, message: bytes, signature: bytes) -> dict: hash = hashlib.sha512(message).digest() return keystore.find_verifying_key(uuid).verify(signature, hash) proto = ProtocolImpl(SIGNED) message = bytes.fromhex( "9512b06eac4d0b16e645088c4622e7451ea5a1ccef01da0040578a5b22ceb3e1" "d0d0f8947c098010133b44d3b1d2ab398758ffed11507b607ed37dbbe006f645" "f0ed0fdbeb1b48bb50fd71d832340ce024d5a0e21c0ebc8e0e") print(proto.message_verify(message))
def __init__(self, alias: str, verifying_key: VerifyingKey, **kwargs): super().__init__(**kwargs) self.alias = alias self.cert = verifying_key.to_bytes() self.timestamp = int(datetime.utcnow().timestamp())
def find_verifying_key(self, uuid: UUID) -> VerifyingKey: """Find the verifying key for this UUID.""" cert = self._ks.certs[uuid.hex] return VerifyingKey(cert.cert)
dongle = getDongle(True) publicKey = dongle.exchange(bytes("8004000000".decode('hex'))) print "publicKey " + str(publicKey).encode('hex') try: offset = 0 while offset <> len(textToSign): if (len(textToSign) - offset) > 255: chunk = textToSign[offset:offset + 255] else: chunk = textToSign[offset:] if (offset + len(chunk)) == len(textToSign): p1 = 0x80 else: p1 = 0x00 apdu = bytes("8002".decode('hex')) + chr(p1) + chr(0x00) + chr( len(chunk)) + bytes(chunk) signature = dongle.exchange(apdu) offset += len(chunk) print "signature " + str(signature).encode('hex') vk = VerifyingKey(bytes(publicKey)) vk.verify(bytes(signature), textToSign) print "verified True" except BadSignatureError: print "verified False" except CommException as comm: if comm.sw == 0x6985: print "Aborted by user" else: print "Invalid status " + comm.sw
def main(): pg_api_key = 'ad68accaab14a18e15afe21f1330acac5ee3bb4d0c2709443b7d4def89b985bc' pg_client_sign_key = '7d9c911ca987e85c90af66511f0ba31ea95996ba7a095b5afcf58df82ae0016c' pg_client_verify_key = '77dbfd30dedf746fb6088017cf5fdcbe59411686784bd5a27ca40cef26cab4f7' api_url = "http://127.0.0.1:59001/api/demo/this_is_api_name" api_name = 'this_is_api_name' data = { 'book':'book name', 'apple': 'apple name', 'cat': 'cat name', 'null_field': None, 'list_field': ['bbbbb','ccccc','aaaaaa'], 'object_field':{ 'ccc': '0000', 'bb': '11111', 'aaa': '22222' }, 'is_ok': True, } data_json_str = json.dumps(data, separators=(',', ':'), sort_keys=True) # 按照key字母顺序排序 print('json_str:{}'.format(data_json_str)) print('------------------------------\n\n') # timestamp_str = str(int(time.time() * 1000)) timestamp_str = '1590156401029' print('tmpstamp_str:{}'.format(timestamp_str)) print('------------------------------\n\n') join_str = '|'.join([timestamp_str, api_name, data_json_str]) print('join_str:{}'.format(join_str)) print('------------------------------\n\n') sign_msg_bytes = join_str.encode('utf8') print('sign_msg_bytes:{}'.format(sign_msg_bytes)) print('------------------------------\n\n') sk = SigningKey(sk_s=pg_client_sign_key.encode('utf8'), prefix='', encoding='hex') signature_bytes = sk.sign(msg=sign_msg_bytes, prefix='', encoding='hex') print('signature_bytes:{}'.format(signature_bytes)) print('------------------------------\n\n') signature_str = signature_bytes.decode('utf8') print('signature_str:{}'.format(signature_str)) print('------------------------------\n\n') req_headers = { 'ContentType': 'application/json', 'PG_API_KEY': pg_api_key, 'PG_API_TIMESTAMP': timestamp_str, 'PG_API_SIGNATURE': signature_str } #请求接口 # rsp = requests.post(url=api_url, json=data, headers=req_headers) try: vk = VerifyingKey(vk_s=pg_client_verify_key, prefix='', encoding='hex') vk.verify(sig=signature_str, msg=sign_msg_bytes, prefix='', encoding='hex') print('验签成功') except Exception as e: print('验签失败') pass
def verify(msg: bytes, sig: bytes, pub: str) -> bool: vkByte = bytes.fromhex(pub) VerifyingKey(vkByte).verify(sig=sig, msg=msg) return True