Rahul Yadav

48 papers A* 2C 1Misc 5Journal 32Unranked 8
YearRankTypeTitle / Venue / Authors
2026 J jnl
J. Field Robotics
Rahul Yadav, Manjeet Singh, Aseem Verma, Naresh Kumar Chhuneja, Derminder Singh, Paramjit Singh
2026 J jnl
Inf. Sci.
Zhihong Wang, Wei Li, Junhui Jiang, Rahul Yadav, Xiaohua Jia, Moustafa Youssef
2025 J jnl
IEEE Trans. Serv. Comput.
Qingyang Fan, Weizhe Zhang, Chen Ling, Rahul Yadav, Hui He
2025 Misc conf
ICASSP
Wenqi Zheng, Jianing Chen, Junze Yang, Chuhao Chen, Wei Li, Rahul Yadav, Xiangxu Meng
2025 J jnl
Clust. Comput.
Rahul Yadav, U. Kumaran, V. P. Meena, Wei Li, Guangsheng Feng, Mohamed Abd Elaziz
2025 conf
ICIC (3)
Bei Wu, Xiangxu Meng, Heng Wang, Rahul Yadav, Geoff Nitschke, Wei Li
2025 Misc conf
ICASSP
Jianing Chen, Chuhao Chen, Junze Yang, Wei Li, Rahul Yadav, Wenqi Zheng
2025 Misc conf
ICASSP
Wenqi Zheng, Jianing Chen, Junze Yang, Chuhao Chen, Wei Li, Rahul Yadav, Xiangxu Meng
2025 Misc conf
ICASSP
Bo Yang, Hongwei Yang, Renhao Lu, Hui He, Weizhe Zhang, Haoyu He, Rahul Yadav
2025 Misc conf
ICASSP
Rokia Abdein, Wei Li, Chenghao Li, Xiangping Zheng, Rahul Yadav
2024 J jnl
IEEE Trans. Consumer Electron.
Muhammad Shafiq, Rahul Yadav, Abdul Rehman Javed, Syed Agha Hassnain Mohsan
2024 J jnl
IEEE Internet Things J.
Chen Ling, Weizhe Zhang, Qingyang Fan, Zebang Feng, Jiayin Wang, Rahul Yadav, Desheng Wang
2024 J jnl
IEEE Internet Things J.
Xiao Sun, Desheng Wang, Weizhe Zhang, Guanqing Lou, Jiayin Wang, Rahul Yadav
2024 J jnl
IEEE Trans. Veh. Technol.
Qingyang Fan, Weizhe Zhang, Chen Ling, Rahul Yadav, Desheng Wang, Hui He
2024 J jnl
IEEE Trans. Veh. Technol.
Chen Ling, Weizhe Zhang, Hui He, Rahul Yadav, Jiayin Wang, Desheng Wang
2023 J jnl
IEEE Trans. Veh. Technol.
Chen Ling, Zebang Feng, Liyan Xu, Qian Huang, Yinsheng Zhou, Weizhe Zhang, Rahul Yadav
2023 J jnl
IEEE Internet Things J.
Sumarga Kumar Sah Tyagi, Rahul Yadav, Deepak Kumar Jain, Yicheng Tu, Weizhe Zhang
2023 conf
INTERACT (2)
Yuchong Zhang, Yueming Xuan, Rahul Yadav, Adel Omrani, Morten Fjeld
2023 J jnl
CoRR
Yuchong Zhang, Yueming Xuan, Rahul Yadav, Adel Omrani, Morten Fjeld
2023 J jnl
Sensors
Rahul Yadav, Florian Ludwig, Fahd Rushd Faridi, J. Michael Klopf, Hartmut G. Roskos, Sascha Preu, Andreas Penirschke
2023 J jnl
J. High Speed Networks
Asif Ali Laghari, Sana Shahid, Rahul Yadav, Shahid Karim, Awais Khan Jumani, Hang Li, Shoulin Yin
2022 A* conf
AAAI
Anjali Gupta, Rahul Yadav, Ashish Nair, Abhijnan Chakraborty, Sayan Ranu, Amitabha Bagchi
2022 J jnl
CoRR
Anjali Gupta, Rahul Yadav, Ashish Nair, Abhijnan Chakraborty, Sayan Ranu, Amitabha Bagchi
2022 A* conf
IJCAI
Ashish Nair, Rahul Yadav, Anjali Gupta, Abhijnan Chakraborty, Sayan Ranu, Amitabha Bagchi
2022 J jnl
CoRR
Ashish Nair, Rahul Yadav, Anjali Gupta, Abhijnan Chakraborty, Sayan Ranu, Amitabha Bagchi
2022 J jnl
IEEE Trans. Computational Imaging
Adel Omrani, Rahul Yadav, Guido Link, Timo Lähivaara, Marko Vauhkonen, John Jelonnek
2022 J jnl
IEEE Trans. Ind. Informatics
Weizhe Zhang, Rahul Yadav, Yu-Chu Tian, Sumarga Kumar Sah Tyagi, Ibrahim A. Elgendy, Omprakash Kaiwartya
2021 J jnl
Mob. Inf. Syst.
I-Sheng Huang, Yu-Hsuan Lu, Muhammad Shafiq, Asif Ali Laghari, Rahul Yadav
2021 J jnl
Sensors
Adel Omrani, Rahul Yadav, Guido Link, Timo Lähivaara, Marko Vauhkonen, John Jelonnek
2021 J jnl
Secur. Commun. Networks
Guozhong Dong, Weizhe Zhang, Haowen Tan, Rahul Yadav, Shuaishuai Tan
2021 J jnl
Clust. Comput.
Rahul Yadav, Weizhe Zhang, Keqin Li, Chuanyi Liu, Asif Ali Laghari
2021 J jnl
Sensors
Rahul Yadav, Adel Omrani, Guido Link, Marko Vauhkonen, Timo Lähivaara
2021 J jnl
Sensors
Yuchong Zhang, Adel Omrani, Rahul Yadav, Morten Fjeld
2020 conf
FICTA (2)
Rahul Yadav, Vikrant Singh, J. Prabhu
2020 conf
ICCCNT
Rinkesh Kumar Dubey, Rahul Yadav, Taimoor Alam, Nirbhay Kumar Singh, Ram Lal Yadava
2020 J jnl
Wirel. Networks
Rahul Yadav, Weizhe Zhang, Keqin Li, Chuanyi Liu, Muhammad Shafiq, Nabin Kumar Karn
2020 J jnl
IEEE Trans. Veh. Technol.
Rahul Yadav, Weizhe Zhang, Omprakash Kaiwartya, Houbing Song, Shui Yu
2020 J jnl
IEEE Trans. Computational Imaging
Timo Lähivaara, Rahul Yadav, Guido Link, Marko Vauhkonen
2019 J jnl
Wirel. Pers. Commun.
Ratnesh Kumari, Rahul Yadav, Piyush N. Patel
2019 C conf
VINCI
Yuchong Zhang, Yong Ma, Adel Omrani, Rahul Yadav, Morten Fjeld, Marco Fratarcangeli
2019 J jnl
EAI Endorsed Trans. Scalable Inf. Syst.
Asif Ali Laghari, Hui He, Rashid Ali Laghari, Asiya Khan, Rahul Yadav
2019 J jnl
Signal Image Video Process.
Nabin Kumar Karn, Hongli Zhang, Feng Jiang, Rahul Yadav, Asif Ali Laghari
2018 J jnl
IEEE Access
Rahul Yadav, Weizhe Zhang, Omprakash Kaiwartya, Prabhat Ranjan Singh, Ibrahim A. Elgendy, Yu-Chu Tian
2018 conf
CVIP (2)
Palash Agrawal, Rahul Yadav, Vikas Yadav, Kanjar De, Partha Pratim Roy
2018 J jnl
IEEE Trans. Instrum. Meas.
Rahul Yadav, Piyush N. Patel
2017 conf
DEXA Workshops
Rahul Yadav, Weizhe Zhang, Huang Chen, Tao Guo
2013 conf
ICACCI
Nitish Saboo, Prajna Pandurang Bhat, Suresh Panwar, Rahul Yadav, G. Ram Mohana Reddy
2011 conf
ICWET
Rahul Yadav, Rukhsana P. Khan, Prashant Sonare
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"