HTTPS Volley无效标头问题 [英] HTTPS Volley Invalid header issue

查看:133
本文介绍了HTTPS Volley无效标头问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先:如果您不知道确切的答案,请给我建议如何检查.谢谢

Before all : if you don't know the exact answer so just give me advice how to check. Thanks

我曾经尝试过很多不同的方法来对我的截击请求实施ssl,但是没有成功.

I have alreary tried a lot of different way how to implement ssl to my volley request but without success.

我无法理解出现此错误的方式

I can not understand way I get this error

ResponseJsonString = <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>Bad Request</TITLE> <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD> <BODY><h2>Bad Request - Invalid Header</h2> <hr><p>HTTP Error 400. The request has an invalid header name.</p> </BODY></HTML>

ResponseJsonString = <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>Bad Request</TITLE> <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD> <BODY><h2>Bad Request - Invalid Header</h2> <hr><p>HTTP Error 400. The request has an invalid header name.</p> </BODY></HTML>

所以逐步执行我的代码

这就是我如何获得凌空队列

This is how I get the volley queue

mRequestQueue = Volley.newRequestQueue(this, new SslHurlStuck(SslUtils.KEYSTORE, SslUtils.PASSWORD_SSL, this));

有我的SslHurlStuck

package utils.ssl;

import android.content.Context;
import android.util.Log;

import com.android.volley.toolbox.HurlStack;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

import utils.global.AppUtils;


public class SslHurlStuck extends HurlStack
{
private final static String TAG = SslHurlStuck.class.getSimpleName();

private String mTrustStoreAssetName;
private String mTrustStorePassword;
private Context mContext;

public SslHurlStuck(final String iTrustStoreAssetName, final String iTrustStorePassword, Context iContext)
{
    super();

    mTrustStoreAssetName = iTrustStoreAssetName;
    mTrustStorePassword = iTrustStorePassword;
    mContext = iContext;
}

@Override
protected HttpURLConnection createConnection(URL url) throws IOException
{
    HttpsURLConnection urlConnection = null;

    try
    {
        urlConnection = new PinnedCertificateHttpsURLConnectionFactory(mContext).createHttpsURLConnection(url.toString(), mTrustStoreAssetName, mTrustStorePassword);
    }
    catch (Throwable iThrowable)
    {
        AppUtils.printLog(Log.ERROR, TAG, iThrowable.getMessage());
    }

    return urlConnection;
}
}

最后是我的PinnedCertificateHttpsURLConnectionFactory

package utils.ssl;

import android.content.Context;
import android.util.Log;

import java.net.URL;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

 import javax.net.ssl.HostnameVerifier;
javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import utils.global.AppUtils;
import webServices.global.RequestStringBuilder;


public class PinnedCertificateHttpsURLConnectionFactory
{
private final static String TAG = PinnedCertificateHttpsURLConnectionFactory.class.getSimpleName();

private final Context mContext;

public PinnedCertificateHttpsURLConnectionFactory(Context iContext)
{
    mContext = iContext;
}

HttpsURLConnection createHttpsURLConnection(String urlString, final String iTrustStoreAssetName, final String iTrustStorePassword) throws Throwable
{
    // Initialize the trust manager factory instance with our trust store
    // as source of certificate authorities and trust material.
    KeyStore trustStore = new TrustStoreFactory(iTrustStoreAssetName, iTrustStorePassword, mContext).createTrustStore();
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm);
    trustManagerFactory.init(trustStore);

    // Initialize the SSL context.
    TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(trustManagerFactory.getTrustManagers());
    SSLContext sslContext = SSLContext.getInstance(SslUtils.PROTOCOL_TLS);
    sslContext.init(null, wrappedTrustManagers, null);

    // Create the https URL connection.
    URL url = new URL(urlString);
    HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
    urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
    urlConnection.setHostnameVerifier(getHostnameVerifier());

    return urlConnection;
}

// Let's assume your server app is hosting inside a server machine
// which has a server certificate in which "Issued to" is "localhost",for example.
// Then, inside verify method you can verify "localhost".
// If not, you can temporarily return true
private HostnameVerifier getHostnameVerifier()
{
    return new HostnameVerifier()
    {
        @Override
        public boolean verify(String hostname, SSLSession session)
        {
            HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();

            String localHost = SslUtils.SSL_LOCAL_HOST_DEV;

            if (RequestStringBuilder.isEnvironmentProd())
            {
                localHost = SslUtils.SSL_LOCAL_HOST_PROD;
            }

            return hv.verify(localHost, session);
            //              return hv.verify("localhost", session);
            //              return true;
        }
    };
}

private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers)
{
    final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];

    final X509TrustManager x509TrustManager = new X509TrustManager()
    {
        public X509Certificate[] getAcceptedIssuers()
        {
            return originalTrustManager.getAcceptedIssuers();
        }

        public void checkClientTrusted(X509Certificate[] certs, String authType)
        {
            try
            {
                if (certs != null && certs.length > 0)
                {
                    for (X509Certificate cer : certs)
                    {
                        cer.checkValidity();
                    }
                }
                else
                {
                    originalTrustManager.checkClientTrusted(certs, authType);
                }
            }
            catch (CertificateException e)
            {
                AppUtils.printLog(Log.ERROR, TAG, "checkClientTrusted" + e.toString());
            }
        }

        public void checkServerTrusted(X509Certificate[] certs, String authType)
        {
            try
            {
                if (certs != null && certs.length > 0)
                {
                    for (X509Certificate cer : certs)
                    {
                        cer.checkValidity();
                    }
                }
                else
                {
                    originalTrustManager.checkServerTrusted(certs, authType);
                }
            }
            catch (CertificateException e)
            {
                AppUtils.printLog(Log.ERROR, TAG, "checkServerTrusted" + e.toString());
            }
        }
    };

    return new TrustManager[] {x509TrustManager};
}
}

最后一个TrustStoreFactory

public class TrustStoreFactory
{
private String mTrustStoreAssetName;
private String mTrustStorePassword;

private Context mContext;

public TrustStoreFactory(final String iTrustStoreAssetName, final String iTrustStorePassword, final Context iContext)
{
    mTrustStoreAssetName = iTrustStoreAssetName;
    mTrustStorePassword = iTrustStorePassword;
    mContext = iContext;
}

KeyStore createTrustStore() throws Throwable
{
    // Retrieve the trust store file from the assets.
    InputStream inputStream = mContext.getAssets().open(mTrustStoreAssetName);

    try
    {
        // Create a key store with the retrieved input stream.
        KeyStore trustStore = KeyStore.getInstance(SslUtils.KEYSTORE_EXTENSION_BKS);

        trustStore.load(inputStream, mTrustStorePassword.toCharArray());

        return trustStore;
    }
    finally
    {
            inputStream.close();
    }
}
}

所以,问题是,我在做什么错?

So, question is , what am I doing wrong?

我的密钥库包含2个cer文件,我尝试了不同的组合将cer添加到密钥库中……但是什么都没有改变.

My keystore consist 2 cer files, I tried different combinations to add the cer to the keystore... but nothing was changed.

实际上,我认为代码没有问题,我认为证书存在一些问题,但是我无法确切理解其内容以及解决方法

Actually I don't think that there is a problems with a code, I think some issue with certificates , but I can not understand what exactly, and how to fix it

另外有趣的是,在iOS中以相同的方式通过相同的ssl检查工作,我们只需要从响应中获取证书,然后在其上按getPublicKey()键,然后比较响应证书中的公钥是否等于该证书的公钥即可.包含在应用程序中...但是在android中要困难得多...

And also what is intresting that in iOS the same ssl checking work in another way, we just need to get certificate from response and then getPublicKey() on it, and compare if public key from response certificate equal to certificate public key that consist within app... But in android it is much more difficult...

随便问

推荐答案

最后,在我的情况下,我不知道为什么,但是我只是从响应中删除了Content-type标头,并且一切正常.

So eventyally in my case, I don't know why , but I just deleted Content-type header with the value from the response, and all is ok.

在这里找到我的答案

Android Volley给了我400错误

这篇关于HTTPS Volley无效标头问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆