Last active
April 27, 2021 07:14
-
-
Save faruktoptas/4b95cbfeafea93176bd3 to your computer and use it in GitHub Desktop.
Public Key Pinning
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public final class PubKeyManager implements X509TrustManager { | |
private String publicKey; | |
public PubKeyManager(String publicKey) { | |
this.publicKey = publicKey; | |
} | |
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { | |
if (chain == null) { | |
throw new IllegalArgumentException( | |
“checkServerTrusted: X509Certificate array is null”); | |
} | |
if (!(chain.length > 0)) { | |
throw new IllegalArgumentException( | |
“checkServerTrusted: X509Certificate is empty”); | |
} | |
// Perform customary SSL/TLS checks | |
TrustManagerFactory tmf; | |
try { | |
tmf = TrustManagerFactory.getInstance(“X509”); | |
tmf.init((KeyStore) null); | |
for (TrustManager trustManager : tmf.getTrustManagers()) { | |
((X509TrustManager) trustManager).checkServerTrusted( | |
chain, authType); | |
} | |
} catch (Exception e) { | |
throw new CertificateException(e.toString()); | |
} | |
// Hack ahead: BigInteger and toString(). We know a DER encoded Public | |
// Key starts with 0x30 (ASN.1 SEQUENCE and CONSTRUCTED), so there is | |
// no leading 0x00 to drop. | |
RSAPublicKey pubkey = (RSAPublicKey) chain[0].getPublicKey(); | |
String encoded = new BigInteger(1 /* positive */, pubkey.getEncoded()) | |
.toString(16); | |
// Pin it! | |
final boolean expected = publicKey.equalsIgnoreCase(encoded); | |
// fail if expected public key is different from our public key | |
if (!expected) { | |
throw new CertificateException( | |
“Not trusted”); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No, this part is standart SSL/TLS checks. Your device checks that if server certificate is trusted or not. You need to do it because you override the TrustManager behaviour.
The pinning part is here:
final boolean expected = publicKey.equalsIgnoreCase(encoded);
This line checks the server certificate's public key if it is the same as the expected public key. If there is a MITM attack public key must be different from your server's public key.