繁体   English   中英

使用Robospice在Android上固定证书

[英]Certificate Pinning on Android with Robospice

我正在阅读Android上的证书固定,我很困惑。 我没有使用okhttp或改装,所以我必须手动完成。 这里有一个教程: https//www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#Android ,他们将证书添加到可信证书列表中。 但是当我们检查服务器上安装的证书的sha256的base64时,还有另一个教程: https//medium.com/@appmattus/android-security-ssl-pinning-1db8acb6621e哪种方法是正确的? 为什么我们不能像浏览器那样从头中的服务器接收sha256并将其存储在某个地方?

我会推荐这个
https://www.paypal-engineering.com/2015/10/14/key-pinning-in-mobile-applications/

Android方法

最简单的方法是使用基于JSEE的方法,如下所示。 这是Android推荐的方法。 方法的输入参数是HTTPS连接和目标URL的一组有效引脚。


private boolean validatePinning(HttpsURLConnection conn, Set<String> validPins) {
    try {
        Certificate[] certs = conn.getServerCertificates();
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        for (Certificate cert : certs) {
            X509Certificate x509Certificate = (X509Certificate) cert;
            byte[] key = x509Certificate.getPublicKey().getEncoded();
            md.update(key, 0, key.length);
            byte[] hashBytes = md.digest();
            StringBuffer hexHash = new StringBuffer();
            for (int i = 0; i < hashBytes.length; i++) {
                int k = 0xFF & hashBytes[i];
                String tmp = (k<16)? "0" : "";
                tmp += Integer.toHexString(0xFF & hashBytes[i]);
                hexHash.append(tmp);
            }
            if (validPins.contains(hexHash.toString())) {
                return true;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return false;
}

引脚被声明为字符串。 例如:

声明关键针脚

private static final Set<String> PINS = new HashSet<String>(Arrays.asList(
        new String[]{
                "996b510ce2380da9c738...87cb13c9ec409941",
                "ba47e83b1ccf0939bb40d2...edf856ba892c06481a"}));

利用上述方法,这里有一个示例,说明如何使用它。 下面突出显示了唯一的相关部分。

使用键固定的示例

protected String doInBackground(String... urls) {
    try {
        /** Test pinning given the target URL **/
        /** for now use pre-defined endpoint URL instead or urls[0] **/
        Log.i(LOG_TAG, "==> PinningTestTask launched.");
        String dest = defaultEndpoint;
        URL targetURL = new URL(dest);
        HttpsURLConnection targetConnection = (HttpsURLConnection) targetURL.openConnection();
        targetConnection.connect();
        if (validatePinning(targetConnection, PINS)) {
            final String updateText = "Key pinning succeded for: " + dest;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    textView.setText(updateText);
                }
            });
        } else {
            final String updateText = "Key pinning failed for: " + dest;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    textView.setText(updateText);
                }
            });
        }
    } catch (Exception e) {
        e.printStackTrace();
        final String updateText = "Key pinning failed for: " + dest + "\n" + e.toString();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText(updateText);
            }
        });
    }
    return null;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM