【问题标题】:Android Client certificate 403Android客户端证书403
【发布时间】:2015-06-15 08:04:45
【问题描述】:

我正在尝试使用带有客户端证书的 ssl 在 android 设备和 Web 服务之间建立连接(服务器检查是否需要客户端证书),服务器上的证书由 CA 签名(go-daddy)我也有一个客户端证书(*.pfx),我休闲this tutorial 附加客户端证书文件, 我正在使用 ksoap2 调用 Web 服务,我不断收到错误 403, 但从设备(或电脑)网络浏览器它工作正常(安装证书后)...... 我对客户端证书了解不多,但在我看来,连接没有以正确的方式使用我的证书。

当我使用自签名证书进行测试时,一切正常。

任何想法我做错了什么? 我的 ksoap2 kod:

public void GetUser(String user_name, String password, boolean isSchedule,
        boolean writeTostatistic) throws Exception {

    Log.d(GlobalUtil.TAG_LOG, "Calling GetUser()  web service");
    String METHOD_NAME = "GetUser";
    globalUtil.user = new User();
    User us = new User();
    HttpsTransportSE httpTransport = new KeepAliveHttpsTransportSE(host,
            port, file, timeout);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
            SoapEnvelope.VER12);
    SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
    httpTransport.debug = true;
    envelope.dotNet = true;
    envelope.headerOut = new Element[1];
    envelope.headerOut[0] = elementHeaders;

    Request.addProperty("user_name", user_name);
    Request.addProperty("password", password);
    Request.addProperty("isSchedule", isSchedule);
    Request.addProperty("writeTostatistic", writeTostatistic);
    envelope.implicitTypes = true;
    envelope.setOutputSoapObject(Request); // prepare request

    envelope.addMapping(NAMESPACE, "User", new User().getClass());

    if (useCertificate) {
        try {
            ((HttpsServiceConnectionSE) httpTransport
                    .getServiceConnection())
                    .setSSLSocketFactory(sSLContext);
        } catch (IOException e) {

            e.printStackTrace();
        }
    } else
        allowAllSSL();

    List<HeaderProperty> httpHeaders = null;
    try {

        httpHeaders = httpTransport.call(SOAP_ACTION + METHOD_NAME,
                envelope, null);

        SoapObject response = (SoapObject) envelope.getResponse();

        if (response == null)
            return;

        us.Id = Integer.parseInt(response.getProperty("Id").toString());
        if (!response.getProperty("User_Name").toString()
                .equals("anyType{}"))
            us.User_Name = response.getProperty("User_Name").toString();
        if (!response.getProperty("Password").toString()
                .equals("anyType{}"))
            us.Password = response.getProperty("Password").toString();
        if (!response.getProperty("USER_HEBREW_FIRSTNAME").toString()
                .equals("anyType{}"))
            us.USER_HEBREW_FIRSTNAME = response.getProperty(
                    "USER_HEBREW_FIRSTNAME").toString();
        if (!response.getProperty("USER_HEBREW_LASTNAME").toString()
                .equals("anyType{}"))
            us.USER_HEBREW_LASTNAME = response.getProperty(
                    "USER_HEBREW_LASTNAME").toString();

        us.Merhav = Integer.parseInt(response.getProperty("Merhav")
                .toString());
        us.Yaam = Integer.parseInt(response.getProperty("Yaam").toString());
        us.Tat_Mifal = Integer.parseInt(response.getProperty("Tat_Mifal")
                .toString());
        us.Ezor = Integer.parseInt(response.getProperty("Ezor").toString());
        us.EzorLahatz = Integer.parseInt(response.getProperty("EzorLahatz")
                .toString());
        /*
         * us.PasswordExpirationDate=(Date)
         * response.getProperty("PasswordExpirationDate");
         */
        us.PasswordExpirationDate = User
                .ParsePasswordExpirationDate((response
                        .getProperty("PasswordExpirationDate").toString()));
        us.Password = password;
        globalUtil.user = us;
        SetSessionCookie(httpHeaders);
        Log.d(GlobalUtil.TAG_LOG, "Finish calling GetUser()  web service");

    } catch (IOException | XmlPullParserException e1) {
        if(e1!=null)
        {
            Log.e(GlobalUtil.TAG_LOG, e1.getMessage());
             throw e1;
        }
        Log.e(GlobalUtil.TAG_LOG, "Error in Login web service.");
        Log.e(GlobalUtil.TAG_LOG, "requestDump: "
                + httpTransport.requestDump);
        Log.e(GlobalUtil.TAG_LOG, "responseDump: "
                + httpTransport.responseDump);
    }

【问题讨论】:

    标签: android ssl certificate client ksoap2


    【解决方案1】:

    对你来说可能为时已晚,但我也有类似的情况......

    旧版本的 Android(和 1.7 之前的 Java)在 SSL 中存在(缺少)SNI 问题。据说这自 2.3 以来已经修复,但我相信我设法在我的 5.0 Android 模拟器中模仿了这个错误。 (可能通过使用自定义套接字上下文工厂。)在浏览器中,我可以使用相同的密钥库/信任库访问 URL,从 Android 我得到 403。

    是什么让我相信确实缺少服务器名称指示是原因......

    openssl s_client -tls1_2 -connect myhost.domain.com:443 -state -cert client.crt -key client.key -pass pass:******** -CAfile server.cer -servername myhost.domain.com
    

    ...在最后省略 -servername 参数会导致 403,这正是我的 Android 代码实现的。 :D

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 2013-03-13
      • 2020-04-12
      • 1970-01-01
      相关资源
      最近更新 更多