簡體   English   中英

客戶端證書無法在Android上運行-如何調試?

[英]Client Certificate not working from Android - How to debug?

到目前為止,我正在嘗試為Android應用程序實施“客戶端證書”通信,但到目前為止並沒有取得很大的成功-而且,即使有可能,此功能也很難實現。 我正在執行的全部流程在上一個問題中進行了描述。

我按照那里的代碼和此博客文章的代碼進行介紹,或多或少地描述了相同的情況,但沒有結果。

什么不起作用:在Android客戶端和服務器之間打開SSL連接( HttpsURLConnection )會使服務器返回403狀態代碼
AFAIK,此403是因為服務器未獲得或不信任它獲得的客戶端證書,並且我不確定如何調試它。

什么有效:

  • 創建PKCS#10請求,將其發送到CA並獲得簽名的PKCS#7( P7B
  • 將帶有私鑰的接收到的P7B存儲在KeyStore中,並將其導出到PKCS#12( P12
  • 最煩人的 )是從設備中挑選P12 ,將其安裝在Windows上,與服務器聯系並獲得一致的(200 HTTP-OK)響應。

我已更改的內容 :從所獲得的代碼示例(從此處此處 )中,我不得不更改一些內容。 我使用的是HttpsURLConnection而不是@Than那里使用的OkHttpClient(但不要緊),我無法像Rich Freedman那樣提供證書(他證書,而我通過PKCS#10和#7),因此我創建了一個CustomTrustManager,它將信任服務器的證書,因此,我使用SpongyCastle(v1.5.0.0,如果重要,設置為插入為0的提供者),並且也不會持久保存證書,但所有操作都在內存中完成。

問題是下一步該怎么做:

  • 我如何知道服務器的期望值(從客戶端證書的角度來看)?
  • 我如何知道哪些客戶端證書(如果有)被發送到服務器?
  • 通常如何調試此方案? (諸如Fiddler之類的代理對於基礎SSL無效)

謝謝!

這不是一個很好的答案,但此處太多內容無法發布為評論。

對於日志記錄,調試可以創建自己的X509KeyManager ,它使用從KeyManagerFactory獲得的普通密鑰管理器:

@DebugLog批注來自Jake Wharton創建的Hugo庫。 它打印函數參數及其返回的內容。 您可以使用普通的Log.d或任何您想要的東西。

例如:

class MyKeyManager implements X509KeyManager {

    private final X509KeyManager keyManager;

    MyKeyManager(X509KeyManager keyManager) {
        this.keyManager = keyManager;
    }

    @DebugLog
    @Override
    public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
        return this.keyManager.chooseClientAlias(strings, principals, socket);
    }

    @DebugLog
    @Override
    public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
        return keyManager.chooseServerAlias(s, principals, socket);
    }

    @DebugLog
    @Override
    public X509Certificate[] getCertificateChain(String s) {
        return keyManager.getCertificateChain(s);
    }

    @DebugLog
    @Override
    public String[] getClientAliases(String s, Principal[] principals) {
        return keyManager.getClientAliases(s, principals);
    }

    @DebugLog
    @Override
    public String[] getServerAliases(String s, Principal[] principals) {
        return keyManager.getServerAliases(s, principals);
    }

    @DebugLog
    @Override
    public PrivateKey getPrivateKey(String s) {
        return keyManager.getPrivateKey(s);
    }
}

並使用它來初始化SSLContext

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, password);

final X509KeyManager origKm = (X509KeyManager) kmf.getKeyManagers()[0];
X509KeyManager km = new MyKeyManager(origKm);

SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(new KeyManager[]{km}, tmf.getTrustManagers(), null);

您將看到調用了哪種方法,參數(從Serwer證書獲得)是什么,以及密鑰管理器返回的證書和私鑰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM