Kagan Tumer

206 papers A* 8A 84B 3C 2Journal 62Unranked 45
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Ayhan Alp Aydeniz, Robert Tyler Loftin, Kagan Tumer
2026 J jnl
CoRR
Raghav Thakar, Gaurav Dixit, Kagan Tumer
2025 A conf
GECCO
Everardo Gonzalez, Gaurav Dixit, Kagan Tumer
2025 conf
GECCO Companion
Everardo Gonzalez, Raghav Thakar, Kagan Tumer
2025 J jnl
Neural Comput. Appl.
Anna Nickelson, Russell Perkins, Alex John London, Paul Robinette, Kagan Tumer
2025 A conf
GECCO
Raghav Thakar, Gaurav Dixit, Siddarth Iyer, Kagan Tumer
2025 A conf
ECAI
Siddarth Iyer, Ayhan Alp Aydeniz, Gaurav Dixit, Kagan Tumer
2025 A conf
AAMAS
Ayhan Alp Aydeniz, Enrico Marchesini, Robert Tyler Loftin, Christopher Amato, Kagan Tumer
2025 conf
GECCO Companion
Raghav Thakar, Kagan Tumer
2024 A conf
AAMAS
Ayhan Alp Aydeniz, Enrico Marchesini, Christopher Amato, Kagan Tumer
2024 A conf
AAMAS
Everardo Gonzalez, Siddarth Viswanathan, Kagan Tumer
2024 A conf
GECCO
Everardo Gonzalez, Siddarth Viswanathan, Kagan Tumer
2024 A conf
AAMAS
Andrew Festa, Gaurav Dixit, Kagan Tumer
2024 A conf
GECCO
Gaurav Dixit, Kagan Tumer
2024 A conf
GECCO
Joshua Cook, Kagan Tumer
2024 conf
GECCO Companion
Joshua Cook, Kagan Tumer
2024 A conf
ECAI
Gaurav Dixit, Kagan Tumer
2024 conf
GECCO Companion
Anna Nickelson, Kagan Tumer
2024 A conf
GECCO
Andrew Festa, Gaurav Dixit, Kagan Tumer
2024 J jnl
CoRR
Ayhan Alp Aydeniz, Enrico Marchesini, Robert Tyler Loftin, Christopher Amato, Kagan Tumer
2023 A* conf
ICRA
Anna Nickelson, Kagan Tumer, William D. Smart
2023 conf
MRS
Ayhan Alp Aydeniz, Enrico Marchesini, Robert Tyler Loftin, Kagan Tumer
2023 A conf
ECAI
Nicholas Zerbel, Kagan Tumer
2023 conf
GECCO Companion
Connor Yates, Kagan Tumer
2023 A conf
AAMAS
Gaurav Dixit, Kagan Tumer
2023 A conf
GECCO
Gaurav Dixit, Kagan Tumer
2023 A conf
GECCO
Joshua Cook, Kagan Tumer, Tristan Scheiner
2023 A conf
AAMAS
Joshua Cook, Tristan Scheiner, Kagan Tumer
2023 A conf
GECCO
Ayhan Alp Aydeniz, Robert Tyler Loftin, Kagan Tumer
2023 C conf
IJCCI
Anna Nickelson, Nicholas Zerbel, Gaurav Dixit, Kagan Tumer
2022 conf
GECCO Companion
Gaurav Dixit, Kagan Tumer
2022 A conf
AAMAS
Gaurav Dixit, Kagan Tumer
2022 conf
GECCO Companion
Golden Rockefeller, Kagan Tumer
2022 A conf
GECCO
Gaurav Dixit, Everardo Gonzalez, Kagan Tumer
2022 conf
GECCO Companion
Ayhan Alp Aydeniz, Anna Nickelson, Kagan Tumer
2022 A conf
GECCO
Joshua Cook, Kagan Tumer
2021 conf
GECCO Companion
Joshua Cook, Kagan Tumer
2021 conf
GECCO Companion
Connor Yates, Ayhan Alp Aydeniz, Kagan Tumer
2021 A conf
AAMAS
Enna Sachdeva, Shauharda Khadka, Somdeb Majumdar, Kagan Tumer
2021 conf
GECCO Companion
Gaurav Dixit, Charles Koll, Kagan Tumer
2021 A conf
GECCO
Enna Sachdeva, Shauharda Khadka, Somdeb Majumdar, Kagan Tumer
2021 conf
MRS
Connor Yates, Ayhan Alp Aydeniz, Kagan Tumer
2020 A* conf
ICML
Somdeb Majumdar, Shauharda Khadka, Santiago Miret, Stephen McAleer, Kagan Tumer
2020 A conf
AAMAS
Gaurav Dixit, Stéphane Airiau, Kagan Tumer
2020 A conf
GECCO
Connor Yates, Reid Christopher, Kagan Tumer
2020 A conf
AAMAS
Golden Rockefeller, Shauharda Khadka, Kagan Tumer
2020 A conf
AAMAS
Nicholas Zerbel, Kagan Tumer
2020 J jnl
Auton. Agents Multi Agent Syst.
Jen Jen Chung, Damjan Miklic, Lorenzo Sabattini, Kagan Tumer, Roland Siegwart
2019 J jnl
Auton. Robots
Jen Jen Chung, Carrie Rebhuhn, Connor Yates, Geoffrey A. Hollinger, Kagan Tumer
2019 A* conf
ICML
Shauharda Khadka, Somdeb Majumdar, Tarek Nassar, Zach Dwiel, Evren Tumer, Santiago Miret, Yinyin Liu, Kagan Tumer
2019 J jnl
CoRR
Shauharda Khadka, Somdeb Majumdar, Tarek Nassar, Zach Dwiel, Evren Tumer, Santiago Miret, Yinyin Liu, Kagan Tumer
2019 A conf
AAMAS
Golden Rockefeller, Patrick Mannion, Kagan Tumer
2019 conf
MRS
Gaurav Dixit, Nicholas Zerbel, Kagan Tumer
2019 J jnl
CoRR
Shauharda Khadka, Somdeb Majumdar, Kagan Tumer
2019 conf
MRS
Golden Rockefeller, Patrick Mannion, Kagan Tumer
2019 A conf
AAMAS
Shauharda Khadka, Connor Yates, Kagan Tumer
2019 conf
MRS
Shauharda Khadka, Connor Yates, Kagan Tumer
2019 J jnl
Artif. Intell. Eng. Des. Anal. Manuf.
Daniel E. Hulse, Kagan Tumer, Christopher Hoyle, Irem Y. Tumer
2019 J jnl
Evol. Comput.
Shauharda Khadka, Jen Jen Chung, Kagan Tumer
2019 A conf
AAMAS
Jen Jen Chung, Damjan Miklic, Lorenzo Sabattini, Kagan Tumer, Roland Siegwart
2018 A conf
AAMAS
Shauharda Khadka, Connor Yates, Kagan Tumer
2018 J jnl
J. Comput. Inf. Sci. Eng.
Nicolás F. Soria Zurita, Mitchell K. Colby, Irem Y. Tumer, Christopher Hoyle, Kagan Tumer
2018 A* conf
NeurIPS
Shauharda Khadka, Kagan Tumer
2018 J jnl
CoRR
Shauharda Khadka, Kagan Tumer
2018 A conf
AAMAS
Jen Jen Chung, Scott Chow, Kagan Tumer
2017 A conf
GECCO
Shauharda Khadka, Jen Jen Chung, Kagan Tumer
2017 J jnl
Auton. Agents Multi Agent Syst.
Mitchell K. Colby, Kagan Tumer
2017 conf
MRS
Shauharda Khadka, Jen Jen Chung, Kagan Tumer
2017 conf
ROBIO
Callie Branyan, Chloe Fleming, Jacquelin Remaley, Ammar Kothari, Kagan Tumer, Ross L. Hatton, Yigit Mengüç
2016 J jnl
J. Aerosp. Inf. Syst.
Mitchell K. Colby, Logan Michael Yliniemi, Kagan Tumer
2016 J jnl
Knowl. Eng. Rev.
Chris HolmesParker, Adrian K. Agogino, Kagan Tumer
2016 A conf
IROS
Aida Rahmattalabi, Jen Jen Chung, Mitchell K. Colby, Kagan Tumer
2016 A conf
AAMAS
Mitchell K. Colby, Theodore Duchow-Pressley, Jen Jen Chung, Kagan Tumer
2016 J jnl
Soft Comput.
Logan Michael Yliniemi, Kagan Tumer
2016 A conf
GECCO
Mitchell K. Colby, Logan Michael Yliniemi, Paolo Pezzini, David Tucker, Kenneth Mark Bryden, Kagan Tumer
2016 A conf
GECCO
Shauharda Khadka, Kagan Tumer, Mitchell K. Colby, Dave Tucker, Paolo Pezzini, Kenneth Mark Bryden
2016 conf
AAMAS Workshops (Visionary Papers)
Logan Michael Yliniemi, Kagan Tumer
2015 A conf
AAMAS
Mitchell K. Colby, Kagan Tumer
2015 A conf
GECCO
Mitchell K. Colby, Kagan Tumer
2015 A conf
AAMAS
Mitchell K. Colby, William J. Curran, Kagan Tumer
2015 conf
GECCO (Companion)
Logan Michael Yliniemi, Kagan Tumer
2015 A conf
AAMAS
Mitchell K. Colby, Sepideh Kharaghani, Chris HolmesParker, Kagan Tumer
2015 A conf
IROS
Mitchell K. Colby, Jen Jen Chung, Kagan Tumer
2015 conf
GECCO (Companion)
Andrew Gabler, Mitchell K. Colby, Kagan Tumer
2015 J jnl
Artif. Life
Atil Iscen, Ken Caluwaerts, Jonathan Bruce, Adrian K. Agogino, Vytas SunSpiral, Kagan Tumer
2015 A conf
IROS
Carrie Rebhuhn, Ryan Skeele, Jen Jen Chung, Geoffrey A. Hollinger, Kagan Tumer
2015 A conf
AAMAS
Logan Michael Yliniemi, Drew Wilson, Kagan Tumer
2015 J jnl
Connect. Sci.
Logan Michael Yliniemi, Adrian K. Agogino, Kagan Tumer
2014 conf
AAAI Spring Symposia
Carrie Rebhuhn, Matt Knudson, Kagan Tumer
2014 A conf
AAMAS
Mitchell K. Colby, William J. Curran, Carrie Rebhuhn, Kagan Tumer
2014 conf
WI-IAT (3)
Chris HolmesParker, Matthew E. Taylor, Adrian K. Agogino, Kagan Tumer
2014 A conf
AAMAS
Chris HolmesParker, Matthew E. Taylor, Adrian K. Agogino, Kagan Tumer
2014 A conf
GECCO
Logan Michael Yliniemi, Adrian K. Agogino, Kagan Tumer
2014 A conf
IROS
Atil Iscen, Adrian K. Agogino, Vytas SunSpiral, Kagan Tumer
2014 A conf
GECCO
William J. Curran, Adrian K. Agogino, Kagan Tumer
2014 conf
SEAL
Logan Michael Yliniemi, Kagan Tumer
2014 conf
AAAI Spring Symposia
Mitchell K. Colby, Matt Knudson, Kagan Tumer
2014 J jnl
AI Mag.
Logan Michael Yliniemi, Adrian K. Agogino, Kagan Tumer
2014 conf
SEAL
Logan Michael Yliniemi, Kagan Tumer
2014 A conf
AAMAS
Sam Devlin, Logan Michael Yliniemi, Daniel Kudenko, Kagan Tumer
2014 A conf
AAMAS
William J. Curran, Adrian K. Agogino, Kagan Tumer
2013 J jnl
Int. J. Gen. Syst.
Max Salichon, Kagan Tumer
2013 A conf
AAMAS
William J. Curran, Adrian K. Agogino, Kagan Tumer
2013 A conf
AAMAS
Chris HolmesParker, Adrian K. Agogino, Kagan Tumer
2013 A conf
GECCO
Atil Iscen, Adrian K. Agogino, Vytas SunSpiral, Kagan Tumer
2013 J jnl
Auton. Agents Multi Agent Syst.
Kagan Tumer, Scott Proper
2013 A conf
AAMAS
Atil Iscen, Kagan Tumer
2013 J jnl
Adv. Complex Syst.
Matt Knudson, Kagan Tumer
2013 J jnl
IEEE Trans. Mob. Comput.
MohammadJavad NoroozOliaee, Bechir Hamdaoui, Kagan Tumer
2013 conf
AAAI (Late-Breaking Developments)
Logan Michael Yliniemi, Kagan Tumer
2013 A conf
AAMAS
Chris HolmesParker, Adrian K. Agogino, Kagan Tumer
2013 A conf
AAMAS
Scott Proper, Kagan Tumer
2013 A conf
AAMAS
Atil Iscen, Adrian K. Agogino, Vytas SunSpiral, Kagan Tumer
2013 A* conf
AAAI
Scott Proper, Kagan Tumer
2013 A conf
AAMAS
Mitchell K. Colby, Kagan Tumer
2013 conf
GECCO (Companion)
William J. Curran, Adrian K. Agogino, Kagan Tumer
2013 J jnl
Int. J. Gen. Syst.
Jaime Junell, Kagan Tumer
2012 J jnl
Auton. Agents Multi Agent Syst.
Adrian K. Agogino, Kagan Tumer
2012 J jnl
Artif. Intell. Res.
Ehsan M. Nasroullahi, Kagan Tumer
2012 J jnl
IEEE Trans. Netw. Serv. Manag.
Bechir Hamdaoui, MohammadJavad NoroozOliaee, Kagan Tumer, Ammar Rayes
2012 J jnl
IEEE Trans. Syst. Man Cybern. Part C
Max Salichon, Kagan Tumer
2012 A conf
GECCO
Adrian K. Agogino, Chris HolmesParker, Kagan Tumer
2012 A conf
GECCO
Adrian K. Agogino, Chris HolmesParker, Kagan Tumer
2012 A conf
AAMAS
Scott Proper, Kagan Tumer
2012 conf
GECCO (Companion)
Matt Knudson, Kagan Tumer
2012 A conf
AAMAS
Mitchell K. Colby, Kagan Tumer
2012 J jnl
AI Mag.
Liz Sonenberg, Peter Stone, Kagan Tumer, Pinar Yolum
2011 A ed.
AAMAS
Liz Sonenberg, Peter Stone, Kagan Tumer, Pinar Yolum
2011 conf
HPCS
MohammadJavad NoroozOliaee, Bechir Hamdaoui, Kagan Tumer
2011 J jnl
Robotics Auton. Syst.
Matt Knudson, Kagan Tumer
2011 A conf
GECCO
Christian Roth, Matt Knudson, Kagan Tumer
2011 B conf
ICCCN
Bechir Hamdaoui, MohammadJavad NoroozOliaee, Kagan Tumer, Ammar Rayes
2011 J jnl
CoRR
Kagan Tumer, David H. Wolpert
2011 A conf
GECCO
Mitchell K. Colby, Ehsan M. Nasroullahi, Kagan Tumer
2010 J jnl
Adv. Complex Syst.
Adrian K. Agogino, Kagan Tumer
2010 A conf
GECCO
Max Salichon, Kagan Tumer
2010 A conf
GECCO
Matt Knudson, Kagan Tumer
2010 A conf
AAMAS
Matt Knudson, Kagan Tumer
2010 A conf
GECCO
Jack F. Shepherd III, Kagan Tumer
2009 conf
ALA
Kagan Tumer, John W. Lawson
2009 J jnl
IEEE Intell. Syst.
Kagan Tumer, Adrian K. Agogino
2009 conf
AAMAS (2)
Adrian K. Agogino, Kagan Tumer
2009 J jnl
Adv. Complex Syst.
Adrian K. Agogino, Kagan Tumer
2009 J jnl
Adv. Complex Syst.
Kagan Tumer, Newsha Khani
2009 conf
AAMAS (2)
Newsha Khani, Kagan Tumer
2009 J jnl
Adv. Complex Syst.
Kagan Tumer, Adrian K. Agogino
2009 ch.
Multi-Agent Systems for Traffic and Transportation Engineering
Kagan Tumer, Zachary T. Welch, Adrian K. Agogino
2008 A* conf
AAAI
Kagan Tumer, Adrian K. Agogino
2008 conf
AAMAS (2)
Kagan Tumer, Zachary T. Welch, Adrian K. Agogino
2008 J jnl
Auton. Agents Multi Agent Syst.
Adrian K. Agogino, Kagan Tumer
2008 J jnl
Inf. Fusion
Nikunj C. Oza, Kagan Tumer
2008 J jnl
Inf. Fusion
Nikunj C. Oza, Kagan Tumer
2008 J jnl
Evol. Comput.
Adrian K. Agogino, Kagan Tumer
2008 J jnl
Pattern Recognit. Lett.
Kagan Tumer, Adrian K. Agogino
2008 conf
AAMAS (2)
Adrian K. Agogino, Kagan Tumer
2007 A conf
AAMAS
Kagan Tumer, Adrian K. Agogino
2007 ch.
Evolutionary Computation in Dynamic and Uncertain Environments
Kagan Tumer, Adrian K. Agogino
2007 A conf
GECCO
Adrian K. Agogino, Kagan Tumer
2006 A conf
AAMAS
Kagan Tumer
2006 A conf
GECCO
Adrian K. Agogino, Kagan Tumer
2006 A conf
AAMAS
Adrian K. Agogino, Kagan Tumer
2006 A conf
AAMAS
Nachi Gupta, Adrian K. Agogino, Kagan Tumer
2006 J jnl
Auton. Agents Multi Agent Syst.
Adrian K. Agogino, Kagan Tumer
2006 A* conf
AAAI
Adrian K. Agogino, Kagan Tumer
2005 A conf
GECCO
Kagan Tumer, Adrian K. Agogino
2005 conf
LAMAS
Kagan Tumer, Adrian K. Agogino
2005 A conf
GECCO
Adrian K. Agogino, Kagan Tumer, Risto Miikkulainen
2005 A conf
AAMAS
Adrian K. Agogino, Kagan Tumer
2004 conf
GECCO (1)
Adrian K. Agogino, Kagan Tumer
2004 B conf
IJCNN
Kagan Tumer, Adrian K. Agogino
2004 A conf
AAMAS
Kagan Tumer, Adrian K. Agogino
2004 A conf
AAMAS
Adrian K. Agogino, Kagan Tumer
2003 conf
Multiple Classifier Systems
Nikunj C. Oza, Kagan Tumer, Irem Y. Tumer, Edward M. Huff
2003 A conf
AAMAS
Kagan Tumer, John W. Lawson
2003 J jnl
CoRR
Kagan Tumer, David H. Wolpert
2003 J jnl
CoRR
David H. Wolpert, Kagan Tumer, Esfandiar Bandari
2003 J jnl
Pattern Anal. Appl.
Kagan Tumer, Nikunj C. Oza
2003 conf
Engineering Self-Organising Systems
Stéphane Airiau, Sandip Sen, David H. Wolpert, Kagan Tumer
2003 A conf
AAMAS
Adrian K. Agogino, Kagan Tumer
2002 J jnl
J. Artif. Intell. Res.
David H. Wolpert, Kagan Tumer
2002 A conf
AAMAS
Kagan Tumer, Adrian K. Agogino, David H. Wolpert
2002 J jnl
Pattern Anal. Appl.
Kagan Tumer, Joydeep Ghosh
2002 J jnl
AI Mag.
Jussi Karlgren, Pentti Kanerva, Björn Gambäck, Kenneth D. Forbus, Kagan Tumer, Peter Stone, Kai Goebel, Gaurav S. Sukhatme, Tucker R. Balch, Bernd Fischer, Doug Smith, Sanda M. Harabagiu, Vinay K. Chaudri, Mike Barley, Hans W. Guesgen, Thomas F. Stahovich, Randall Davis, James A. Landay
2001 conf
Multiple Classifier Systems
Nikunj C. Oza, Kagan Tumer
2001 J jnl
Adv. Complex Syst.
David H. Wolpert, Kagan Tumer
2001 A* conf
IJCAI
David H. Wolpert, Joseph Sill, Kagan Tumer
2000 conf
Agents
David H. Wolpert, Sergey Kirshner, Christopher J. Merz, Kagan Tumer
2000 conf
AAAI/IAAI
Kagan Tumer, David H. Wolpert
1999 J jnl
CoRR
David H. Wolpert, Sergey Kirshner, Christopher J. Merz, Kagan Tumer
1999 J jnl
CoRR
David H. Wolpert, Kagan Tumer
1999 J jnl
CoRR
Kagan Tumer, David H. Wolpert
1999 J jnl
CoRR
David H. Wolpert, Kevin R. Wheeler, Kagan Tumer
1999 J jnl
CoRR
Kagan Tumer, Nirmala Ramanujam, Joydeep Ghosh, Rebecca R. Richards-Kortum
1999 J jnl
CoRR
David H. Wolpert, Kevin R. Wheeler, Kagan Tumer
1999 conf
Agents
David H. Wolpert, Kevin R. Wheeler, Kagan Tumer
1999 J jnl
CoRR
Kagan Tumer, Joydeep Ghosh
1999 J jnl
CoRR
Kagan Tumer, Joydeep Ghosh
1999 J jnl
CoRR
David H. Wolpert, Kagan Tumer, Jeremy Frank
1998 J jnl
IEEE Trans. Biomed. Eng.
Kagan Tumer, Nirmala Ramanujam, Joydeep Ghosh, Rebecca R. Richards-Kortum
1998 conf
NIPS
David H. Wolpert, Kagan Tumer, Jeremy Frank
1996 J jnl
Pattern Recognit.
Kagan Tumer, Joydeep Ghosh
1996 J jnl
Connect. Sci.
Kagan Tumer, Joydeep Ghosh
1996 B conf
ICPR
Kagan Tumer, Joydeep Ghosh
1996 conf
NIPS
Kagan Tumer, Nirmala Ramanujam, Rebecca R. Richards-Kortum, Joydeep Ghosh
1995 J jnl
IEEE Trans. Syst. Man Cybern.
José Nelson Amaral, Kagan Tumer, Joydeep Ghosh
1994 C conf
IEA/AIE
Kagan Tumer, Joydeep Ghosh
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"