Xiang Su

102 papers A* 5A 3B 10C 3Misc 2Journal 46Unranked 32
YearRankTypeTitle / Venue / Authors
2025 B conf
VRST
Vishal Chauhan, Anubhav, Robin Sidhu, Yu Asabe, Kanta Tanaka, Chia-Ming Chang, Xiang Su, Ehsan Javanmardi, Takeo Igarashi, Alex Orsholits, Kantaro Fujiwara, Manabu Tsukada
2025 J jnl
IEEE Trans. Mob. Comput.
Dianlei Xu, Xiang Su, Gopika Premsankar, Huandong Wang, Sasu Tarkoma, Pan Hui
2025 J jnl
IEEE Trans. Mob. Comput.
Yuanwei Zhu, Yakun Huang, Xiuquan Qiao, Xiaoli Liu, Xiang Su, Anna Brunström, Özgü Alay, Sasu Tarkoma
2025 conf
SIGCOMM (Posters and Demos)
Boyu Fan, Xiang Su, Sasu Tarkoma, Pan Hui
2025 J jnl
IEEE Netw.
Xiaoli Liu, Xiang Su, Guillermo del Campo, Jacky Cao, Boyu Fan, Edgar Saavedra, Asunción Santamaria, Juha Röning, Pan Hui, Sasu Tarkoma
2025 J jnl
ACM Trans. Internet Techn.
Boyu Fan, Xiang Su, Sasu Tarkoma, Pan Hui
2025 J jnl
Frontiers Inf. Technol. Electron. Eng.
Yongjie Yin, Hui Ruan, Yang Chen, Jiong Chen, Ziyue Li, Xiang Su, Yipeng Zhou, Qingyuan Gong
2025 J jnl
ACM Trans. Internet Things
Farooq Ayoub Dar, Mayowa Olapade, Abdul-Rasheed Ottun, Zhigang Yin, Mohan Liyanage, Ulrich Norbisrath, Marko Radeta, Francisco Airton Silva, Xiang Su, Janick Edinger, Petteri Nurmi, Huber Flores
2025 J jnl
IEEE Commun. Mag.
Dianlei Xu, Xiang Su, Sasu Tarkoma, Pan Hui
2025 J jnl
Int. J. Hum. Comput. Stud.
Vishal Chauhan, Anubhav, Chia-Ming Chang, Xiang Su, Jin Nakazato, Ehsan Javanmardi, Alex Orsholits, Takeo Igarashi, Kantaro Fujiwara, Manabu Tsukada
2025 J jnl
IEEE Trans. Mob. Comput.
Yakun Huang, Shengwei Meng, Yuanwei Zhu, Jun Wang, Jacky Cao, Xiuquan Qiao, Xiang Su
2024 B conf
IEEE Big Data
Boyu Fan, Siyang Jiang, Xiang Su, Sasu Tarkoma, Pan Hui
2024 J jnl
ACM Trans. Intell. Syst. Technol.
Ekaterina Gilman, Francesca Bugiotti, Ahmed Khalid, Hassan Mehmood, Panos Kostakos, Lauri Tuovinen, Johanna Ylipulli, Xiang Su, Denzil Ferreira
2024 J jnl
ACM Trans. Sens. Networks
Boyu Fan, Xiang Su, Sasu Tarkoma, Pan Hui
2024 conf
ECCV (83)
Boyu Fan, Chenrui Wu, Xiang Su, Pan Hui
2024 J jnl
CoRR
Boyu Fan, Chenrui Wu, Xiang Su, Pan Hui
2024 J jnl
IEEE Netw.
Yaru Zhao, Yakun Huang, Ping Lu, Wenzhe Shi, Baojun Ma, Xiang Su, Xiuquan Qiao
2024 J jnl
IEEE Trans. Mob. Comput.
Yuanwei Zhu, Yakun Huang, Xiuquan Qiao, Jian Tang, Xiang Su
2024 J jnl
IEEE J. Sel. Areas Commun.
Yakun Huang, Boyuan Bai, Yuanwei Zhu, Xiuquan Qiao, Xiang Su, Lei Yang, Ping Zhang
2024 J jnl
IEEE Netw.
Yakun Huang, Haowen Wang, Xiuquan Qiao, Xiang Su, Yang Li, Schahram Dustdar, Ping Zhang
2024 J jnl
IEEE Trans. Mob. Comput.
Dianlei Xu, Xiang Su, Huandong Wang, Sasu Tarkoma, Pan Hui
2023 conf
ImmerCom
Xiaoli Liu, Tormod Mork Müller, Aleksander Aaboen, Xiang Su, Sasu Tarkoma
2023 conf
AINA (2)
Gianluca Rizzo, Alberto Franzin, Miia Lillstrang, Guillermo del Campo, Moisés Silva-Muñoz, Lluc Bono, Mina Aghaei Dinani, Xiaoli Liu, Joonas Tuutijärvi, Satu Tamminen, Edgar Saavedra, Asunción Santamaria, Xiang Su, Juha Röning
2023 conf
CoNEXT (Short Papers)
Giovanni Bartolomeo, Jacky Cao, Xiang Su, Nitinder Mohan
2023 J jnl
IEEE Trans. Mob. Comput.
Nan Qi, Zanqi Huang, Wen Sun, Shi Jin, Xiang Su
2023 J jnl
IEEE Trans. Mob. Comput.
Boyu Fan, Xiang Su, Jianwei Niu, Pan Hui
2023 J jnl
IEEE Computer Graphics and Applications
Jacky Cao, Hassan Mehmood, Xiaoli Liu, Sasu Tarkoma, Ekaterina Gilman, Xiang Su
2023 J jnl
IEEE Trans. Veh. Technol.
Chen Chen, Yong Niu, Bo Ai, Ruisi He, Zhu Han, Zhangdui Zhong, Ning Wang, Xiang Su
2023 J jnl
ACM Comput. Surv.
Jacky Cao, Kit-Yung Lam, Lik-Hang Lee, Xiaoli Liu, Pan Hui, Xiang Su
2023 J jnl
CoRR
Boyu Fan, Siyang Jiang, Xiang Su, Pan Hui
2023 Misc conf
SenSys
Xiang Su, Luyi Sun, Pan Hui
2023 A conf
MobiSys
Hui Ruan, Qingyuan Gong, Yang Chen, Jiong Chen, Ziyue Li, Xiang Su
2023 conf
IXR@MM
Jacky Cao, Xiang Su, Pan Hui
2023 conf
iThings/GreenCom/CPSCom/SmartData/Cybermatics
Xiang Su, Ekaterina Gilman, Xiaoli Liu
2023 J jnl
IEEE Internet Things J.
Naser Hossein Motlagh, Pranvera Kortoçi, Xiang Su, Lauri Lovén, Hans Kristian Hoel, Sindre Bjerkestrand Haugsvær, Varun Srivastava, Casper Fabian Gulbrandsen, Petteri Nurmi, Sasu Tarkoma
2022 J jnl
Computer
Naser Hossein Motlagh, Lauri Lovén, Jacky Cao, Xiaoli Liu, Petteri Nurmi, Schahram Dustdar, Sasu Tarkoma, Xiang Su
2022 conf
IUI Companion
Xiang Su, Ai Jiang, Jacky Cao, Wenxiao Zhang, Pan Hui, Juan Ye
2022 J jnl
CoRR
Yakun Huang, Xiuquan Qiao, Haowen Wang, Xiang Su, Schahram Dustdar, Ping Zhang
2022 A* conf
ACM Multimedia
Abhishek Kumar, Lik-Hang Lee, Jagmohan Chauhan, Xiang Su, Mohammad Ashraful Hoque, Susanna Pirttikangas, Sasu Tarkoma, Pan Hui
2022 J jnl
IEEE Pervasive Comput.
Zhigang Yin, Mayowa Olapade, Mohan Liyanage, Farooq Dar, Agustin Zuniga, Naser Hossein Motlagh, Xiang Su, Sasu Tarkoma, Pan Hui, Petteri Nurmi, Huber Flores
2022 J jnl
IEEE Commun. Mag.
Yakun Huang, Yuanwei Zhu, Xiuquan Qiao, Xiang Su, Schahram Dustdar, Ping Zhang
2022 J jnl
CoRR
Yakun Huang, Yuanwei Zhu, Xiuquan Qiao, Xiang Su, Schahram Dustdar, Ping Zhang
2022 conf
ICDE Workshops
Xiaoli Liu, Satu Tamminen, Sasu Tarkoma, Xiang Su
2022 B conf
GLOBECOM
Nan Qi, Yeting Huang, Wen Sun, Shi Jin, Theodoros A. Tsiftsis, Qihui Wu, Xiang Su
2021 conf
PerCom Workshops
Jacky Cao, Xiang Su
2021 A conf
ICDCS
Ahmad Yousef Alhilal, Tristan Braud, Xiang Su, Luay Al Asadi, Pan Hui
2021 B conf
GLOBECOM
Jacky Cao, Xiaoli Liu, Xiang Su, Sasu Tarkoma, Pan Hui
2021 J jnl
CoRR
Boyu Fan, Xiang Su, Jianwei Niu, Pan Hui
2021 conf
MSN
Jacky Cao, Xiang Su, Benjamin Finley, Antti Pauanne, Mostafa H. Ammar, Pan Hui
2021 J jnl
CoRR
Jacky Cao, Kit-Yung Lam, Lik-Hang Lee, Xiaoli Liu, Pan Hui, Xiang Su
2020 A* conf
MobiCom
Xiang Su, Jacky Cao, Pan Hui
2020 conf
MobiHealth
Lei Fang, Xiaoli Liu, Xiang Su, Juan Ye, Simon Dobson, Pan Hui, Sasu Tarkoma
2020 A* conf
PerCom
Boyu Fan, Xuefeng Liu, Xiang Su, Pan Hui, Jianwei Niu
2020 J jnl
Sensors
Yuhong Li, Xiang Su, Aaron Yi Ding, Anders Lindgren, Xiaoli Liu, Christian Prehofer, Jukka Riekki, Rahim Rahmani, Sasu Tarkoma, Pan Hui
2020 J jnl
CoRR
Jacky Cao, Xiang Su, Benjamin Finley, Pengyuan Zhou, Pan Hui
2020 Misc conf
SenSys
Xiaoxin He, Xiang Su, Yang Chen, Pan Hui
2020 B conf
ICMI
Lik Hang Lee, Ngo Yan Yeung, Tristan Braud, Tong Li, Xiang Su, Pan Hui
2020 conf
ICDE Workshops
Ekaterina Gilman, Satu Tamminen, Anja Keskinarkaus, Theodoros Anagnostopoulos, Xiang Su, Susanna Pirttikangas, Jukka Riekki
2020 A* conf
PerCom
Lik-Hang Lee, Yiming Zhu, Yui-Pan Yau, Tristan Braud, Xiang Su, Pan Hui
2020 conf
ICDE Workshops
Carlos Bermejo, Ting Wu, Xiang Su, Pan Hui
2020 B conf
NOMS
Yuhong Li, Di Jin, Bailin Wang, Xiang Su, Jukka Riekki, Chao Sun, Hanyu Wei, Hao Wang, Lei Han
2019 B conf
CBMS
Xiaoli Liu, Xiang Su, Satu Tamminen, Topi Korhonen, Juha Röning
2019 J jnl
Proc. ACM Interact. Mob. Wearable Ubiquitous Technol.
Lik Hang Lee, Kit-Yung Lam, Tong Li, Tristan Braud, Xiang Su, Pan Hui
2018 A* conf
PerCom
Xiang Su, Pingjiang Li, Jukka Riekki, Xiaoli Liu, Jussi Kiljander, Juha-Pekka Soininen, Christian Prehofer, Huber Flores, Yuhong Li
2018 conf
PerCom Workshops
Xiaoli Liu, Satu Tamminen, Xiang Su, Pekka Siirtola, Juha Röning, Jukka Riekki, Jussi Kiljander, Juha-Pekka Soininen
2017 B conf
SMC
Yuhong Li, Haoyue Xue, Zhihui Gai, Xirong Que, Xiang Su, Jukka Riekki
2017 conf
IOT
Yuhong Li, Xiaoyu Hao, Han Zheng, Xiang Su, Jukka Riekki, Chao Sun, Hanyu Wei, Hao Wang, Lei Han
2017 conf
ICC
Yuhong Li, Yuanyuan Huang, Xiang Su, Jukka Riekki, Huber Flores, Chao Sun, Hanyu Wei, Hao Wang, Lei Han
2017 conf
CHANTS@MOBICOM
Yuhong Li, Ji Wang, Anders Lindgren, Xiang Su, Jukka Riekki
2017 conf
PerCom Workshops
Huber Flores, Xiang Su, Vassilis Kostakos, Aaron Yi Ding, Petteri Nurmi, Sasu Tarkoma, Pan Hui, Yong Li
2017 A conf
ICDCS
Huber Flores, Xiang Su, Vassilis Kostakos, Jukka Riekki, Eemil Lagerspetz, Sasu Tarkoma, Pan Hui, Yong Li, Jukka Manner
2017 J jnl
IEEE Internet Things J.
Altti Ilari Maarala, Xiang Su, Jukka Riekki
2017 C conf
GPC
Xiang Su, Pingjiang Li, Huber Flores, Jukka Riekki, Xiaoli Liu, Yuhong Li, Christian Prehofer
2016 conf
ICC
Yuhong Li, Xiang Su, Jukka Riekki, Theo Kanter, Rahim Rahmani
2016 J jnl
Comput. Commun.
Julien Mineraud, Oleksiy Mazhelis, Xiang Su, Sasu Tarkoma
2016 conf
IOV
Yuhong Li, Xiang Su, Anders Lindgren, Xinyue Shi, Xiang Cai, Jukka Riekki, Xirong Que
2016 conf
IEEE BigData
Susanna Pirttikangas, Ekaterina Gilman, Xiang Su, Teemu Leppänen, Anja Keskinarkaus, Mika Rautiainen, Mikko Pyykkönen, Jukka Riekki
2016 B conf
MUM
Georgios Pipelidis, Xiang Su, Christian Prehofer
2016
Xiang Su
2016 J jnl
CoRR
Xiang Su, Jarkko Hyysalo, Mika Rautiainen, Jukka Riekki, Jaakko J. Sauvola, Altti Ilari Maarala, Harri Honko
2016 J jnl
Computer
Xiang Su, Jarkko Hyysalo, Mika Rautiainen, Jukka Riekki, Jaakko J. Sauvola, Altti Ilari Maarala, Harri Hirvonsalo, Pingjiang Li, Harri Honko
2016 J jnl
CoRR
Altti Ilari Maarala, Xiang Su, Jukka Riekki
2016 conf
WIMS
Xiang Su, Ekaterina Gilman, Peter Wetz, Jukka Riekki, Yifei Zuo, Teemu Leppänen
2016 conf
IOT
Xiang Su, Pingjiang Li, Yuhong Li, Huber Flores, Jukka Riekki, Christian Prehofer
2015 J jnl
CoRR
Julien Mineraud, Oleksiy Mazhelis, Xiang Su, Sasu Tarkoma
2015 J jnl
Concurr. Comput. Pract. Exp.
Xiang Su, Jukka Riekki, Jukka K. Nurminen, Johanna Nieminen, Markus Koskimies
2015 J jnl
CoRR
Julien Mineraud, Oleksiy Mazhelis, Xiang Su, Sasu Tarkoma
2014 J jnl
J. Ambient Intell. Smart Environ.
Xiang Su, Ekaterina Gilman, Jukka Riekki
2014 conf
ANT/SEIT
Xiang Su, Hao Zhang, Jukka Riekki, Ari Keränen, Jukka K. Nurminen, Libin Du
2014 conf
IOT
Altti Ilari Maarala, Xiang Su, Jukka Riekki
2013 J jnl
J. Ambient Intell. Smart Environ.
Ekaterina Gilman, Oleg Davidyuk, Xiang Su, Jukka Riekki
2012 J jnl
Pers. Ubiquitous Comput.
Xiang Su, Jukka Riekki, Janne Haverinen
2011 conf
GPC Workshops
Jiehan Zhou, Xiang Su, Mika Ylianttila, Jukka Riekki
2011 conf
AmI
Xiang Su, Ekaterina Gilman, Pawel Kwiatkowski, Tomasz Latkowski, Alma Pröbstl, Bartlomiej Wójtowicz, Jukka Riekki
2011 J jnl
Int. J. Pervasive Comput. Commun.
Ekaterina Gilman, Xiang Su, Oleg Davidyuk, Jiehan Zhou, Jukka Riekki
2010 conf
ISAmI
Xiang Su, Davide Fucci, Jukka Riekki
2010 conf
SSN
Xiang Su, Jukka Riekki
2010 C conf
EJC
Ekaterina Gilman, Xiang Su, Jukka Riekki
2010 C conf
EUC
Xiang Su, Jukka Riekki
2009 B conf
Intelligent Environments
Xiang Su, Jukka Riekki, Sasu Tarkoma
2009 conf
FCST
Jiehan Zhou, Jun-Zhao Sun, Mika Rautiainen, Oleg Davidyuk, Meirong Liu, Ekaterina Gilman, Xiang Su, Mika Ylianttila, Jukka Riekki
2009 conf
ICINCO-ICSO
Xiang Su, Jukka Riekki, Janne Haverinen
redb/extractors/apk_extractors/apk_signature.py
← Index redb/extractors/apk_extractors/apk_signature.py python
import hashlib
import inspect
from datetime import datetime, timezone
from typing import Any, Optional, Tuple

from redb.extractors.enum import Tag
from redb.extractors.apk_extractor import APKExtractor
from redb.models.dataclasses import APKCertificate, APKCodeSigningInfo


# OID to RFC 4514 short name mapping
_OID_SHORT_NAMES = {
    '2.5.4.3': 'CN', '2.5.4.6': 'C', '2.5.4.7': 'L', '2.5.4.8': 'ST',
    '2.5.4.10': 'O', '2.5.4.11': 'OU', '1.2.840.113549.1.9.1': 'E',
    '2.5.4.5': 'SERIALNUMBER', '2.5.4.12': 'T', '2.5.4.42': 'GN',
    '2.5.4.4': 'SN', '2.5.4.9': 'STREET', '2.5.4.17': 'POSTALCODE',
}


def _asn1_name_to_rfc4514(name):
    """Convert an asn1crypto x509.Name to RFC 4514 string (CN=..., O=...)."""
    parts = []
    for rdn in name.chosen:
        for attr in rdn:
            oid = attr['type'].dotted
            val = attr['value'].native
            short = _OID_SHORT_NAMES.get(oid, oid)
            parts.append(f'{short}={val}')
    return ', '.join(parts)


class APKSignatureExtractor(APKExtractor):

    def __init__(
        self, filepath, log, exporters=None, index_prefix=None,
        known_benign=False, known_malicious=False,
        apk=None,
    ):
        super().__init__(
            filepath, log, exporters, index_prefix,
            known_benign, known_malicious, apk,
        )
        self.signing_info = None
        self.log.debug(inspect.currentframe().f_code.co_name)

    def tag(self):
        return Tag.APK_SIGNATURE.value

    def _detect_signature_schemes(self):
        """Detect which APK signature schemes are present."""
        schemes = []
        try:
            if self.apk.is_signed_v1():
                schemes.append(1)
        except Exception:
            pass
        try:
            if self.apk.is_signed_v2():
                schemes.append(2)
        except Exception:
            pass
        try:
            if self.apk.is_signed_v3():
                schemes.append(3)
        except Exception:
            pass
        return schemes

    def _extract_certificate_info(self, cert, source_scheme=None):
        """Extract certificate details from an androguard certificate object."""
        try:
            # Subject and Issuer — asn1crypto doesn't have rfc4514_string, convert manually
            subject = _asn1_name_to_rfc4514(cert.subject)
            issuer = _asn1_name_to_rfc4514(cert.issuer)

            # Serial number
            serial = str(cert.serial_number)

            # Validity
            valid_from = cert.not_valid_before
            valid_to = cert.not_valid_after
            if isinstance(valid_from, datetime):
                valid_from = valid_from.strftime("%Y-%m-%d %H:%M:%S")
            else:
                valid_from = str(valid_from)
            if isinstance(valid_to, datetime):
                valid_to = valid_to.strftime("%Y-%m-%d %H:%M:%S")
            else:
                valid_to = str(valid_to)

            # Thumbprints
            cert_der = cert.dump()
            thumbprint_sha1 = hashlib.sha1(cert_der).hexdigest()
            thumbprint_sha256 = hashlib.sha256(cert_der).hexdigest()

            # Algorithm
            algorithm = None
            try:
                algorithm = cert.hash_algo
            except Exception:
                try:
                    algorithm = cert.signature_algo
                except Exception:
                    pass

            # Key size
            key_size = None
            try:
                pub_key = cert.public_key
                if hasattr(pub_key, 'bit_size'):
                    key_size = pub_key.bit_size
                elif hasattr(pub_key, 'key_size'):
                    key_size = pub_key.key_size
            except Exception:
                pass

            # Self-signed check
            is_self_signed = cert.subject == cert.issuer

            return APKCertificate(
                subject=subject,
                issuer=issuer,
                serial_number=serial,
                valid_from=valid_from,
                valid_to=valid_to,
                thumbprint_sha1=thumbprint_sha1,
                thumbprint_sha256=thumbprint_sha256,
                algorithm=algorithm,
                key_size=key_size,
                is_self_signed=is_self_signed,
                certificate_source_scheme=source_scheme,
            )
        except Exception as e:
            self.log.error(f"Error extracting certificate info: {e}")
            return None

    def _get_signer_certificate(self, schemes) -> Tuple[Optional[APKCertificate], Optional[str]]:
        """Identify the actual signer certificate using V3>V2>V1 priority.

        V2/V3: certificates[0] is the signer per spec.
        V1: androguard's get_certificate() does SignerInfo matching internally.

        Returns (signer_cert_info, source_scheme) or (None, None).
        """
        # V3 takes priority (Android 9+)
        if 3 in schemes:
            try:
                certs = self.apk.get_certificates_v3()
                if certs:
                    cert_info = self._extract_certificate_info(certs[0], source_scheme='v3')
                    if cert_info:
                        return cert_info, 'v3'
            except Exception as e:
                self.log.debug(f"V3 signer extraction failed: {e}")

        # V2 next (Android 7.0+)
        if 2 in schemes:
            try:
                certs = self.apk.get_certificates_v2()
                if certs:
                    cert_info = self._extract_certificate_info(certs[0], source_scheme='v2')
                    if cert_info:
                        return cert_info, 'v2'
            except Exception as e:
                self.log.debug(f"V2 signer extraction failed: {e}")

        # V1 fallback — androguard does SignerInfo.issuerAndSerialNumber matching
        if 1 in schemes:
            try:
                names = self.apk.get_signature_names()
                if names:
                    cert = self.apk.get_certificate(names[0])
                    if cert:
                        cert_info = self._extract_certificate_info(cert, source_scheme='v1')
                        if cert_info:
                            return cert_info, 'v1'
            except Exception as e:
                self.log.debug(f"V1 signer extraction failed: {e}")

        return None, None

    def _extract_all_certificates(self, schemes):
        """Extract all certificates with their source scheme tracked.

        Uses scheme-specific methods to preserve source information,
        deduplicating by thumbprint_sha1 and merging source schemes.
        """
        # cert thumbprint -> (APKCertificate, set of source schemes)
        seen = {}

        for scheme_num, method_name in [
            (3, 'get_certificates_v3'),
            (2, 'get_certificates_v2'),
            (1, 'get_certificates_v1'),
        ]:
            if scheme_num not in schemes:
                continue
            try:
                method = getattr(self.apk, method_name, None)
                if method is None:
                    continue
                certs = method()
                if not certs:
                    continue
                for cert in certs:
                    cert_info = self._extract_certificate_info(cert, source_scheme=f'v{scheme_num}')
                    if cert_info:
                        key = cert_info.thumbprint_sha1
                        if key in seen:
                            # Merge source schemes
                            existing_cert, existing_schemes = seen[key]
                            existing_schemes.add(f'v{scheme_num}')
                        else:
                            seen[key] = (cert_info, {f'v{scheme_num}'})
            except Exception as e:
                self.log.warning(f"Error extracting v{scheme_num} certificates: {e}")

        # Build final list with merged source schemes
        result = []
        for cert_info, source_schemes in seen.values():
            cert_info.certificate_source_scheme = ','.join(sorted(source_schemes))
            result.append(cert_info)

        return result

    def extract(self):
        if not self._is_valid_apk():
            self.log.error(f"Invalid APK for {self.hash.sha256}")
            return None

        schemes = self._detect_signature_schemes()
        is_signed = len(schemes) > 0

        # Extract all certificates with source scheme tracking
        certificates = self._extract_all_certificates(schemes)

        # Identify the actual signer using V3>V2>V1 priority
        signer_cert, signer_scheme = self._get_signer_certificate(schemes)

        apk_signer_subject = signer_cert.subject if signer_cert else None
        apk_signer_issuer = signer_cert.issuer if signer_cert else None

        self.signing_info = APKCodeSigningInfo(
            _id=self.sha256,
            is_signed=is_signed,
            signature_scheme_versions=schemes,
            number_of_certificates=len(certificates),
            x509_certificates=certificates if certificates else None,
            apk_signer_subject=apk_signer_subject,
            apk_signer_issuer=apk_signer_issuer,
        )
        return self.signing_info

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ClickHouseExporter":
            if not self.signing_info:
                return None

            current_time = datetime.now(timezone.utc)
            sig = self.signing_info

            # Signature summary table
            signature_data = [[
                self.sha256,
                int(sig.is_signed),
                sig.signature_scheme_versions,
                sig.number_of_certificates,
                sig.apk_signer_subject,
                sig.apk_signer_issuer,
                current_time,
            ]]

            # Certificates table (one row per certificate)
            certificates_data = []
            if sig.x509_certificates:
                for cert in sig.x509_certificates:
                    certificates_data.append([
                        self.sha256,
                        cert.subject,
                        cert.issuer,
                        cert.serial_number,
                        datetime.strptime(cert.valid_from, "%Y-%m-%d %H:%M:%S") if cert.valid_from else None,
                        datetime.strptime(cert.valid_to, "%Y-%m-%d %H:%M:%S") if cert.valid_to else None,
                        cert.thumbprint_sha1,
                        cert.algorithm,
                        cert.key_size,
                        int(cert.is_self_signed),
                        cert.certificate_source_scheme,
                        current_time,
                    ])

            return {
                'multi_table': True,
                'signature': {
                    'table': 'redb_apk_signature',
                    'data': signature_data,
                    'column_names': [
                        'sha256',
                        'is_signed', 'signature_scheme_versions',
                        'number_of_certificates',
                        'apk_signer_subject', 'apk_signer_issuer',
                        'analysis_date',
                    ],
                    'column_type_names': [
                        'FixedString(64)',
                        'UInt8', 'Array(UInt8)',
                        'UInt8',
                        'Nullable(String)', 'Nullable(String)',
                        "DateTime64(3, 'UTC')",
                    ],
                },
                'certificates': {
                    'table': 'redb_apk_certificates',
                    'data': certificates_data,
                    'column_names': [
                        'sha256', 'certificate_subject', 'certificate_issuer',
                        'certificate_serial_number',
                        'certificate_valid_from', 'certificate_valid_to',
                        'certificate_thumbprint',
                        'certificate_algorithm', 'key_size', 'is_self_signed',
                        'certificate_source_scheme',
                        'analysis_date',
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'String', 'String', 'String',
                        "DateTime64(3, 'UTC')", "DateTime64(3, 'UTC')",
                        'FixedString(40)',
                        'LowCardinality(String)', 'Nullable(UInt16)', 'UInt8',
                        'LowCardinality(String)',
                        "DateTime64(3, 'UTC')",
                    ],
                },
            }

    def get_clickhouse_table(self) -> str:
        return "redb_apk_signature"