class UbirchProtocol(object): """ The ubirch-protocol packages data into a protocol wrapper, taking care of signing data, chaining of signatures and verification of incoming messages. """ ECC_ENCRYPTION_OID = (1, 2, 1, 3, 101, 112) def __init__(self, uuid: UUID, keystore_file: str, password: str) -> None: """Initialize the ubirch-protocol for the device with the given UUID.""" super().__init__() self._uuid = uuid.hex self._ks_file = keystore_file self._ks_password = password self._load_or_create_keys() def _load_or_create_keys(self) -> None: """Load or create new crypto-keys. The keys are stored in a local key store.""" if not self._uuid: raise Exception("missing UUID to load key from keystore") # try to load the keystore or create a new one try: self._ks = jks.KeyStore.load(self._ks_file, self._ks_password) except FileNotFoundError: log.warning("creating new key store: {}".format(self._ks_file)) self._ks = jks.KeyStore.new("jks", []) # load the key if self._uuid in self._ks.private_keys: sk = self._ks.private_keys[self._uuid] self._signingKey = SigningKey(sk.pkey) log.info("loaded signing key for {}".format(self._uuid)) else: self._signingKey, vk = ed25519.create_keypair(entropy=urandom) # encode the ED25519 private key as PKCS#8 ed25519_algorithm_oid = self.ECC_ENCRYPTION_OID private_key_info = rfc5208.PrivateKeyInfo() private_key_info.setComponentByName('version', 'v1') a = AlgorithmIdentifier() a.setComponentByName('algorithm', ed25519_algorithm_oid) private_key_info.setComponentByName('privateKeyAlgorithm', a) private_key_info.setComponentByName('privateKey', self._signingKey.to_bytes()) pkey_pkcs8 = encoder.encode(private_key_info) pke = jks.PrivateKeyEntry.new(alias=str(self._uuid), certs=[], key=pkey_pkcs8) self._ks.entries[self._uuid] = pke self._ks.save(self._ks_file, self._ks_password) log.info("created new signing key for {}".format(self._uuid)) def pack_key_registration(self) -> bytes: now = datetime.utcnow() created = self._time_format(now) not_before = self._time_format(now) not_after = self._time_format(now + timedelta(days=365)) pub_key_enc = bytes.decode( base64.b64encode(self._sk.get_verifying_key().to_bytes())) pub_key_info = { "hwDeviceId": self._serial, "pubKey": pub_key_enc, "pubKeyId": pub_key_enc, "algorithm": 'ECC_ED25519', "created": created, "validNotBefore": not_before, "validNotAfter": not_after } pub_key_info_enc = str.encode( json.dumps(pub_key_info, sort_keys=True, separators=(',', ':'))) signature = bytes.decode( base64.b64encode(self._sk.sign(pub_key_info_enc))) payload = {"pubKeyInfo": pub_key_info, "signature": signature} return str.encode( json.dumps(payload, sort_keys=True, separators={',', ":"}))
def find_signing_key(self, uuid: UUID) -> SigningKey: """Find the signing key for this UUID.""" sk = self._ks.private_keys['pke_' + uuid.hex] return SigningKey(sk.pkey)
def sign_msg(sign_key: str, msg: bytes) -> any: sk = SigningKey(sk_s=sign_key.encode('latin1'), prefix='', encoding='hex') sig = sk.sign(msg=msg, prefix='', encoding='hex') return sig
logger = logging.getLogger() ERRORS = 0 UBIRCH_CLIENT = os.getenv("UBIRCH_CLIENT") if UBIRCH_CLIENT and not UBIRCH_CLIENT.strip(): UBIRCH_CLIENT = None UBIRCH_ENV = os.getenv("UBIRCH_ENV") UBIRCH_AUTH = os.getenv("UBIRCH_AUTH") # test UUID uuid = UUID(hex=os.getenv('UBIRCH_DEVICE_UUID', "00000000-0000-0000-0000-000000000000")) sk = SigningKey(binascii.unhexlify(os.getenv('UBIRCH_PRIV_KEY'))) vk = sk.get_verifying_key() logger.debug("UBIRCH_CLIENT = '{}'".format(UBIRCH_CLIENT)) logger.debug("UBIRCH_ENV = '{}'".format(UBIRCH_ENV)) logger.debug("UBIRCH_AUTH = '{}'".format(UBIRCH_AUTH)) logger.debug("UBIRCH_DEVICE_UUID = '{}'".format(uuid)) NAGIOS_OK = 0 NAGIOS_WARNING = 1 NAGIOS_ERROR = 2 NAGIOS_UNKNOWN = 3 def nagios(client, env, service, code, message="OK"): global ERRORS
def sign(self, privKey: ed25519.SigningKey) -> None: self.signature = privKey.sign(b"MEROS" + self.hash)
def sign_bytes(bytes_to_sign: bytes, private_key: ed25519.SigningKey) -> bytes: sig = private_key.sign(bytes_to_sign) return sig
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 publicKeyFromPrivate(priv: str) -> str: skByte = bytes.fromhex(priv) return SigningKey(skByte).get_verifying_key().to_bytes().hex()
def sign(msg: bytes, priv: str) -> bytes: skByte = bytes.fromhex(priv) skSigning = SigningKey(skByte) return skSigning.sign(msg)