各种编程语言忽略http的SSL证书认证

前言

我们内部测试的http服务器很多时候证书都是没有经过第三方认证的,我们发送http请求基本上都是忽略证书认证。
我总结了一下常用编程语言使用http请求时忽略证书认证的代码片段,记录一下下。

代码

go语言

func httpPost(url, body string) ([]byte, error) {
    req, err := http.NewRequest(http.MethodPost, urlPre+url, strings.NewReader(body))
    if err != nil {
        return nil, err
    }
    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
 
    client := &http.Client{ // 忽略证书验证
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        },
    }
    resp, err := client.Do(req)
    if resp != nil {
        defer resp.Body.Close()
    }
    if err != nil {
        return nil, err
    }
 
    data, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }
    return data, nil
}

Python语言

import json
import requests

try:
    # verify = False 表示忽略证书
    response = requests.post("//www.baidu.com/",verify = False, headers = header, data = "")
    data = json.loads(response.text)
    print(data)
except Exception as e:
    print('error:', e)

Ruby语言

require 'rest-client'
require 'json'
 
begin
    # :verify_ssl => OpenSSL::SSL::VERIFY_NONE 表示忽略证书
    resp = RestClient::Request.execute(method: :post, url: "//www.baidu.com/", payload: "", headers: headers, :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
    data = JSON.parse(resp.body)
    puts(data)
rescue => e
    puts("#{e.class}, #{e.message}")
end

Java语言

package iotp;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.X509Certificate;
 
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
 
public class janbar {
    public static void main(String[] args) {
        trustAllHosts(); // 只在开头执行一次即可
 
        String data = httpPost("//www.baidu.com/", "");
        System.out.println(data);
    }
 
    public static String httpPost(String httpUrl, String param) {
        HttpsURLConnection connection = null;
        InputStream is = null;
        OutputStream os = null;
        BufferedReader br = null;
        String result = null;
        try {
            // 通过远程url连接对象打开连接
            connection = (HttpsURLConnection) new URL(urlPre + httpUrl).openConnection();
            // 忽略证书认证
            connection.setHostnameVerifier(DO_NOT_VERIFY);
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60000毫秒
            connection.setReadTimeout(60000);
 
            // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
            connection.setDoOutput(true);
            // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
            connection.setDoInput(true);
            // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 通过连接对象获取一个输出流
            os = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            os.write(param.getBytes());
            // 通过连接对象获取一个输入流,向远程读取
            if (connection.getResponseCode() == 200) {
                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
 
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            connection.disconnect();
        }
        return result;
    }
 
    private static void trustAllHosts() {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[] {};
            }
 
            public void checkClientTrusted(X509Certificate[] chain, String authType) {
            }
 
            public void checkServerTrusted(X509Certificate[] chain, String authType) {
            }
        } };
        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    private final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
}

PHP语言

<?php
function httpPost($url, $content) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type','application/x-www-form-urlencoded'));
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
    $response = curl_exec($ch);
    if($error=curl_error($ch)){
        die($error);
    }
    curl_close($ch);
    return $response;
}
$data = httpPost("//www.baidu.com/", "");
$data = json_decode($data, true);
var_dump($data);

C#语言

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
 
namespace SundrayApi
{
    class Program
    {
        static void Main(string[] args)
        {
            string data = apiPost("//www.baidu.com/", "");
            Console.WriteLine(data);
 
            Console.ReadLine();
        }
 
        static string apiPost(string url, string body)
        {
            string content = string.Empty;
            try
            {
                /* 跳过ssl验证 */
                ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
                HttpWebRequest request = HttpWebRequest.Create(preUrl + url) as HttpWebRequest;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                byte[] data = Encoding.UTF8.GetBytes(body);
                Stream newStream = request.GetRequestStream();
                newStream.Write(data, 0, data.Length);
                newStream.Close();
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream stream = response.GetResponseStream();
                StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                content = reader.ReadToEnd();
                reader.Close();
                response.Close();
            }
            catch (Exception ex)
            {
                content = ex.ToString();
            }
            return content;
        }
    }
}

C/C++语言

c语言需要编译一下下,如下流程即可。
wget //curl.haxx.se/download/curl-7.73.0.tar.gz
./configure
make
gcc test.c -l curl -L /root/c/curl/curl-7.73.0/lib/.libs -I /root/c/curl/curl-7.73.0/include

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
 
typedef struct {
  char *memory;
  size_t size;
} MemoryStruct;
 
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  MemoryStruct *mem = (MemoryStruct *)userp;
 
  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) { /* out of memory! */
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }
  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}
 
int httpPost(const char *url, char *data, int size)
{
    int ret = -1;
    if(url == NULL || data == NULL){
        return ret;
    }
 
    CURL *curl = curl_easy_init();
    struct curl_slist* headers;
    long   retcode = 0;
 
    MemoryStruct chunk;
    chunk.size   = 0;
    chunk.memory = malloc(1);
 
    headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
 
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
 
    CURLcode res = curl_easy_perform(curl);
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &retcode);
    if (res == CURLE_OK && retcode == 200) {
        ret = 0;
        if (chunk.size > 0) {
            if (chunk.size > size)
                chunk.size = size - 1; /* 超出限制,不拷贝 */
            memcpy(data, chunk.memory, chunk.size);
        }
        data[chunk.size] = 0; /* 结束符 */
    } else {
        ret = -2;
    }
 
    curl_easy_cleanup(curl);
    free(chunk.memory);
    return ret;
}
  
int main(int argc, char *argv[])
{
    int url_len = 128, data_len = 2048;
    char *url  = (char *)malloc(sizeof(char) * url_len);
    char *data = (char *)malloc(sizeof(char) * data_len);
 
    strcpy(url,  "//www.baidu.com/");
    strcpy(data, "");
    int ret = httpPost(url, data, data_len);
    if (ret != 0) {
        return ret;
    }
    printf("[%s]\n\n",data);
    return 0;
}

shell语言

#!/bin/bash

# 使用 -k 参数忽略证书
data=$(curl -s -k "//www.baidu.com/" -d "")
echo "$data"

总结

把常用编程语言的http忽略证书代码做个笔记,方便以后再来查看。本来想谢谢lua的,但是lua连socket都得编译个库来搞,还是以后有需求再搞搞吧。
另外再附上https跳过证书校验底层原理