Is it easy to reverse engineer the app and check the certificates it is pinned against if we specify the hashes as plain text in network_security_config.xml
? I've come across an opinion, that such constants should be stored in an app as e.g. an array of bytes to make it harder for an attacker to reason, what is going on in the app and why it doesn't want to talk to his server. That array of bytes could be then turned into a proper string somewhere in an obfuscated code. Of course it doesn't prevent the attack, but it makes it a bit harder. What can be considered a best practice when implementing certificate pinning on Android?
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="false">abc.aaa</domain>
<pin-set>
<pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
</pin-set>
</domain-config>
</network-security-config>
It's straightforward to extract the xmls from an apk using apktool. That said, having the hash of the SSL cert's public key isn't very useful as it's quite difficult to generate another to have the same key (and SSL certs are changed every one or two years anyway) and usually what attackers may do is to change the xml and repackage the app to use another pinned certificate and then analyze the packets to understand the communication protocol/data formats. Or they can just decompile the dex/bytecode and look directly at the code that handles the communication. If you have really sensitive data and wish to increase its level of protection while in transit, you can add an extra layer of encryption before you send/receive it using HTTPS. Note however that nowadays data is most vulnerable while it's on the user's device (in RAM or storage) as OSs are notorious for countless vulnerabilities (known and unknown) that are remain unfixed for years. It really depends whom you are trying to keep that data from...