tomcat https双向认证(包含PC端和移动端操作)

使用tomcat配置TLS双向认证 最近要搞一个内部服务,只允许内网访问,而且必须的安装证书才可以调用该接口,就需要使用tomcat配置TLS双向认证,参看了很多文章,比较好的一篇推荐如下:https://blog.youkuaiyun.com/u011682673/article/details/77825720 jdk版本:1.8.0_211 tomcat版本:8.5.51 一、生成证书 A、生成服务器证书 使用jdk自带的keytools工具生成证书,进入jdk的目录: D:\programfiles\jdk1.8.0_211> 阅读详情

原理:

个人理解:双向认证就是客户端和服务器之间互相认证,客户端拿着自己的证书和服务器的公钥证书去服务器认证,服务器拿着自己的证书和客服端公钥认证客户端。服务器私钥解密客户端拿服务器公钥加密的数据。客户端拿自己的私钥解密服务器拿客户端公钥加密的数据。

操作 :

本地需要有jdk环境和配置

1:通过jdktools生成服务器证书

创建服务器密钥,其密钥库为 d:/mykeys/server.ks,注意keypass和storepass保持一致,
 它们分别代表 密钥密码和密钥库密码,注意 CN=localhost 中,localhost表示要配置SSL的主机名,不能任意指定  也可以不写。
 

keytool -genkey -v -alias serverKey -dname "CN=localhost" -keyalg RSA -keypass rwm258 -keystore server.ks -storepass rwm258

生成服务器证书后tomcat或者nginx配置后就可以实现单项认证

2;导出服务器公钥证书

keytool -export -alias serverKey -file server.cer -keystore server.ks -storepass rwm258

3:创建客户端密钥,其密钥库为 d:/mykeys/client.p12,注意这个密钥库的后缀名,注意密钥库类型PKCS12

keytool -genkey -v -alias clientKey -dname "CN=SomeOne" -keyalg RSA -keypass lyl147 -keystore client.p12 -storepass lyl147 -storetype PKCS12

4:客户端密钥导出为证书文件公钥文件

keytool -export -alias clientKey -file clientKey.cer -keystore client.p12 -storepass lyl147 -storetype PKCS12

5:将上述客户端密钥文件导入服务器证书库,并设置为信任证书;注意会问你是否信任该证书,回答 y 即可

keytool -import -v -alias clientKey -file clientKey.cer -keystore server.ks -storepass rwm258

目前为止证书生成结束。。。

开始配置环境操作。。。

6:编辑tomcat配置文件server.xml

	<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"

			maxThreads="150" scheme="https" secure="true"

			clientAuth="true" sslProtocol="TLS"

			keystoreFile="D:/mykeys/server.ks" keystorePass="rwm258"

			truststoreFile="D:/mykeys/server.ks " truststorePass=" rwm258" />

服务器只需要配置服务器证书就行了。。。然后启动tomcat

 为了在本机浏览器中进行SSL访问,请:双击 d:/mykeys/client.p12 ,将启动证书向导

导入的文件,为私钥键入密码lyl147 ,将所有的证书放入下列存储区,然后,浏览-个人

保存证书,打开chrome浏览器设置 搜索SSL ,安全设置,管理证书中就可以看到sameone证书。

然后输入https://localhost:8443/

弹出选择证书的操作点击确定 即可

这样PC端的双向认证就完成了。。。

Android移动端认证:之前导出了服务器的公钥,,现在就用到了。。

首先Android 需要bks格式的证书这需要工具转换下,,,下载portecle

https://jaist.dl.sourceforge.net/project/portecle/v1.11/portecle-1.11.zip

然后打开工具

打开本地的客户端证书 client.p12 输入密码 lyl147

然后选择tools  --change  keystoretype --BKS  然后保存。。输入client.bks。这样就有了生成了客户端的bks证书文件

把客户端证书client.bks 和服务器的公钥证书放入本地assets下

Android Webview 配置双向认证:

package com.collect.baselib.myUtils;
 
import android.annotation.TargetApi;
import android.net.Uri;
import android.os.Build;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.collect.baselib.BaseApplication;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
 
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
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;
 
public class SslWebViewClient extends WebViewClient {
 
    private SSLContext sslContext;
 
    public SslWebViewClient() {
        try {
            TrustManager[] trustManagers = prepareTrustManager(BaseApplication.getAppContext().getResources().getAssets().open("server.cer"));
            KeyManager[] keyManagers = prepareKeyManager(BaseApplication.getAppContext().getResources().getAssets().open("client.bks"), "lyl147");
            sslContext = SSLContext.getInstance("TLS");
            X509TrustManager trustManager = null;
            if (null != trustManagers){
                trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
            }else {
                trustManager = new UnSafeTrustManager();
            }
            sslContext.init(keyManagers, new TrustManager[]{trustManager}, new SecureRandom());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        return processRequest(Uri.parse(url));
    }
 
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        return processRequest(request.getUrl());
    }
 
    private WebResourceResponse processRequest(Uri uri) {
        try {
            //设置连接
            URL url = new URL(uri.toString());
            HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
            //为request设置SSL Socket Factory
            urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
 
            urlConnection.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
 
            //获取请求的内容、contentType、encoding
            InputStream inputStream = urlConnection.getInputStream();
            String contentType = urlConnection.getContentType();
            String encoding = urlConnection.getContentEncoding();
            if (null != contentType){
                String mimeType = contentType;
                if (contentType.contains(";")){
                    mimeType = contentType.split(";")[0].trim();
                }
                //返回新的response
                return new WebResourceResponse(mimeType, encoding, inputStream);
            }
 
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    private TrustManager[] prepareTrustManager(InputStream... certificates) {
        if (certificates == null || certificates.length <= 0){
            return null;
        }
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e){
 
                }
            }
            TrustManagerFactory trustManagerFactory = null;
            trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            return trustManagers;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
 
    }
 
    private KeyManager[] prepareKeyManager(InputStream bksFile, String password) {
        try {
            if (bksFile == null || password == null){
                return null;
            }
            KeyStore clientKeyStore = KeyStore.getInstance("BKS");
            clientKeyStore.load(bksFile, password.toCharArray());
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(clientKeyStore, password.toCharArray());
            return keyManagerFactory.getKeyManagers();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
        for (TrustManager trustManager : trustManagers) {
            if (trustManager instanceof X509TrustManager) {
                return (X509TrustManager) trustManager;
            }
        }
        return null;
    }
 
    public static class MyTrustManager implements X509TrustManager{
        private X509TrustManager defaultTrustManager;
        private X509TrustManager localTrustManager;
 
        public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException {
            TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            var4.init((KeyStore) null);
            defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
            this.localTrustManager = localTrustManager;
        }
 
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
 
        }
 
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            try {
                defaultTrustManager.checkServerTrusted(chain, authType);
            } catch (CertificateException ce) {
                localTrustManager.checkServerTrusted(chain, authType);
            }
        }
 
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }
 
    public static class UnSafeTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
 
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
 
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }
    }
 
 
}

webview使用

his.setWebViewClient(new SslWebViewClient());

接口请求okhttp和webview需要单独设置,,很多类似代码可以参考:这里客户端和服务器的都是bks格式的,,也可以加载cer的。修改下就行了

package com.collect.baselib.myUtils;

import android.content.Context;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

/**
 * @author: created by whq
 * date: 2021/9/17
 */

public class SSLHelper {
    private final static String CLIENT_PRI_KEY = "geren.bks";
    private final static String TRUSTSTORE_PUB_KEY = "service.bks";
    private final static String CLIENT_BKS_PASSWORD = "";
    private final static String TRUSTSTORE_BKS_PASSWORD = "";
    private final static String KEYSTORE_TYPE = "BKS";
    private final static String PROTOCOL_TYPE = "TLS";
    private final static String CERTIFICATE_STANDARD = "X509";

    public static SSLSocketFactory getSSLCertifcation(Context context) {
        SSLSocketFactory sslSocketFactory = null;
        try {
            // 服务器端需要验证的客户端证书,其实就是客户端的keystore
            KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
            // 客户端信任的服务器端证书
            KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);

            //读取证书
            InputStream ksIn = context.getAssets().open(CLIENT_PRI_KEY);
            InputStream tsIn = context.getAssets().open(TRUSTSTORE_PUB_KEY);

            //加载证书
            keyStore.load(ksIn, CLIENT_BKS_PASSWORD.toCharArray());
            trustStore.load(tsIn, TRUSTSTORE_BKS_PASSWORD.toCharArray());
            ksIn.close();
            tsIn.close();


            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(CERTIFICATE_STANDARD);
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(CERTIFICATE_STANDARD);
            trustManagerFactory.init(trustStore);
            keyManagerFactory.init(keyStore, CLIENT_BKS_PASSWORD.toCharArray());

            //初始化SSLContext
            SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new java.security.SecureRandom());

            sslSocketFactory = sslContext.getSocketFactory();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslSocketFactory;
    }
}

然后okhttp设置:

 OkHttpClient.Builder builder = new OkHttpClient.Builder();
//            builder.sslSocketFactory(sslSocketFactory);

            builder.sslSocketFactory(SSLHelper.getSSLCertifcation(BaseApplication.getAppContext()), new SSLHttpsUtil.UnSafeTrustManager());
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

这样接口调用也就认证成功了。。。

IOS认证可以参考  IOS之https请求认证及双向认证_gb_wxzqq的博客-优快云博客_ios 双向认证

本文参考:

Android webview在https下实现ssl的双向认证_张zx的博客-优快云博客

TOMCAT-SSL双向认证-配置实例_nimmy的博客-优快云博客

tomcat实现https双向认证配置_a18792721831的博客-优快云博客_tomcat双向认证

补充  和有用。。。

发现PC端直接导入一个客户端证书就可以打开地址,那webView也是一个浏览器是不是可以实现给webview安装一个证书实现所有的https的链接读取呢?尝试了下发现可以实现

    @Override
    public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {

        try {
            PrivateKey privateKey = null;
            X509Certificate[] certificates = null;             

            // 服务器端需要验证的客户端证书,其实就是客户端的keystore
            KeyStore keyStore = KeyStore.getInstance("BKS");


            //读取证书
            InputStream ksIn = BaseApplication.getAppContext().getAssets().open("geren.bks");


            //加载证书
            keyStore.load(ksIn, "".toCharArray());


            Enumeration<String> aliases = keyStore.aliases();
            String alias = aliases.nextElement();

            Key key = keyStore.getKey(alias, "".toCharArray());
            if (key instanceof PrivateKey) {
                privateKey = (PrivateKey) key;
                Certificate cert = keyStore.getCertificate(alias);
                certificates = new X509Certificate[1];
                certificates[0] = (X509Certificate) cert;
            }

            ksIn.close();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                request.proceed(privateKey, certificates);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }

    @Override
    public void onReceivedSslError(final WebView view, SslErrorHandler handler,
                                   SslError error) {
        handler.proceed();
    }

这样接口调用用双证书,webview 就直接加载客户端证书就行了,,而且webview读取本地H5代码都不会再次校验。。

Tomcat双向SSL认证及CA数字证书安装和配置&QQ即时通信协议窥探(1) 如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。欢迎大家一起交流讨论啊~《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。[外链图片转存中…(img-hViXHcHR-1712299890849)]欢迎大家一起交流讨论啊~《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》, 阅读详情

相关推荐

Unity实时通信利器:NativeWebSocket跨平台开发与实战指南

WebSocket作为一种全双工通信协议,实现了客户端与服务器之间的持久化双向数据流传输,其核心原理是在单个TCP连接上建立低延迟、高效率的实时通道。这一特性使其在游戏开发、物联网和实时数据可视化等领域具有重要技术价值,尤其适用于多人在线游戏同步、实时聊天室和动态仪表盘等需要即时数据交换的应用场景。NativeWebSocket作为Unity平台的WebSocket解决方案,通过封装各平台原生网络库,提供了统一的异步API,有效解决了跨平台兼容性和性能优化问题,帮助开发者构建稳定的实时通信应用。

weixin_30613727的博客 455

11. 利用Tomcat服务器配置HTTPS双向认定

【代码】11. 利用Tomcat服务器配置HTTPS双向认定。

大头鱼 3320

软件测试常见面试题2(附答案)

表单的主要作用是接收用户的输入,当用户提交表单时,浏览器将用户在表单中输入的数据打包,并发送给服务器,从而实现用户与Web服务器的交互。Tcpdump是Linux系统自带的抓包命令,流经网卡的数据都能抓到,抓取到的内容比较多。但同时,特别是对于一个较大的网站的,涉及到上百甚至上千个页面,链接测试需要较大的测试量,因此,提高测试的效率成了网站链接测试的一个重要方面。是的,http协议的特征无连接,就是只浏览器与web服务器不会保持长时间的连接状态,只要客户端请求得到响应,连接就会断开。

m0_52603036的博客 90

基于tomcat的https(ssl)双向认证

某个供应商服务需要部署到海外,如果海外多个地区需要部署多个服务,最好能实现统一登录,这样可以减轻用户的使用负担(不用记录一堆密码)。由于安全问题(可能会泄露用户数据),海外服务不能直连公司sso服务端,因此需要其他的方案解决安全问题。最终的安全方案中需要用到SSL双向认证进行数据的传输和交互,并且只指定某些个别接口实现SSL双向认证。在此背景下,这篇文章介绍基于tomcat的SSL双向认证的简单实现。

lgq2016的博客 3437

【信息科学与工程学】计算机科学与自动化——第八十一篇 Java分布式软件高并发/高可用算法01

4. 消息队列(如Kafka的Topic分区,本质是范围)。3. 若是ACCEPT事件,bossGroup线程接受连接,创建SocketChannel,并将其注册到workerGroup的一个EventLoop的Selector上,关注READ事件。1. 分布式缓存分片(如Redis Cluster)。4. 分布式文件存储(如Ceph CRUSH)。6. 调用栈的模拟(如协程)。3. 服务网格(如Istio)的基础。2. 本地缓存与集中式缓存(如Redis)的一致性维护。3. 静态数据(如配置)缓存。

weixin_49199313的博客 1234

【深度学习】手把手教你在远程服务器上跑 YOLOv3 相关代码(含环境配置)

这篇文章主要记录了如何配置项目环境以及如何在远程服务器上跑 YOLOv3 模型。

作者正在煮茶中... 2384

https双向认证

https双向认证

u014644574的博客 1万+

CCC数字钥匙3.0标准解读(16)

介绍通信过程最重要部分:身份认证和加密.介绍需要身份认证的过程和需要加密的数据及过程.

weixin_41738640的博客 1535

Android HTTPS 自制证书实现双向认证(OkHttp + Retrofit + Rxjava)

由于最近要做一个安全性比较高的项目,因此需要用到HTTPS进行双向认证。由于设计项目架构的时候,客户端是采用MVVM架构,基于DataBinding + Retrofit + Rxjava来实现Android端。 查阅很多资料,基于原生HttpClient实现双向认证的例子很多,但对于Retrofit的资料网上还是比较少,官方文档也是一句带过,没有具体的介绍。 看了 《Android中https请...

AndroidAlvin的博客 320

RK3568+XS9922B+Android11双模视频输入:CVBS与AHD兼容驱动开发实战

本文详细介绍了基于RK3568平台和XS9922B解码芯片,在Android11系统上开发支持CVBS与AHD双模视频输入的兼容驱动实战。内容涵盖硬件选型、内核驱动框架分析、双模信号自动识别与配置、视频通道切换实现及图像质量优化等关键技术点,为车载监控等需要兼容新旧摄像头的项目提供完整解决方案。

js777的博客 379

iOS开发者必备:从越狱设备里提取IPA的三种方法(含Filza、iTools实战)

本文详细介绍了iOS开发者从越狱设备提取IPA文件的三种实用方法,包括使用Filza文件管理器、AFC2配合桌面工具以及命令行高级技术。内容涵盖环境准备、操作步骤和技术原理,帮助开发者高效获取应用包文件,适用于逆向工程、测试分析等场景。

weixin_28717969的博客 821

UnityWebSocket快速集成指南:5分钟实现跨平台实时通信

WebSocket作为一种全双工通信协议,通过在单个TCP连接上提供双向通信通道,解决了传统HTTP协议在实时数据传输中的高延迟和效率瓶颈问题。其核心原理是建立持久连接,允许服务器主动向客户端推送数据,显著降低了通信开销。这一特性使其在需要低延迟、高频率数据交换的场景中具有重要技术价值,广泛应用于多人在线游戏、实时聊天、金融行情推送和物联网设备控制等领域。UnityWebSocket作为一个专为Unity引擎设计的开源库,封装了WebSocket客户端功能,提供了对开发者友好的API接口和跨平台兼容性,帮助

weixin_34332905的博客 461

1、CUDA 编程基础

GPU计算的发展历程与重要性。首先回顾了计算机技术的发展,特别是摩尔定律的影响,强调了计算能力的快速提升。然而,随着晶体管尺寸的缩小和频率的停滞,单线程性能增长放缓。为了继续提升性能,多核处理器开始普及,促使软件开发者开始考虑并行计算。介绍了延迟导向设计和吞吐量导向设计的概念,CPU和GPU分别代表了这两种设计方法。GPU是吞吐量导向的,拥有众多弱小的ALU,通过流水线处理提高算术吞吐量。GPU的成功在于其高并行性和高吞吐量,以及能够分摊高昂的固定成本的大量销售额。

Justinyh的博客 580

JavaWeb学习

#前端部分(了解)课程思路、前端要素(Web了解、html、JS、vue、ajax、Element等)传统路线现在课程大纲路线## 前端要素(Web了解、html)HTML语法特点基本标签html标签(span)html标签(a)html标签(video)盒子模型:html标签(div)html标签(表格)html标签(表单)## 前端要素(JS)JS引入方式JS基础语法JS函数JS对象(基础(只关注Array、String、JSON)、BOM、DOM)JS事件监听## 前端要素(Vue)插值表达式Vue常

qq_2634545805的博客 430

手把手保姆级|Python爬取微信公众号文章完整版,反反爬策略拉满,附可运行完整代码(永久可用)

做Python爬虫的朋友都知道,爬取微信公众号文章 绝对是爬虫领域的「香饽饽」也是「硬骨头」。一方面,微信公众号的文章是极具价值的数据源:不管是自媒体从业者做竞品分析、新媒体运营者整理干货、还是个人学习收集资料,都需要批量爬取公众号文章;另一方面,微信的反爬机制堪称全网最严苛之一 ——腾讯对微信生态的风控做到了极致,动态渲染页面、高频IP封禁、Cookie短时效失效、请求头严格校验、自动化工具秒识别、频繁请求直接拉黑,这些反爬手段让90%的爬虫新手望而却步:要么爬了几篇就被封IP,要么Cookie失效爬取中

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2629

基于STM32设计的智能防盗单车锁_349

本设计基于STM32F103RCT6单片机,研制了一种适用于户外环境的智能防盗单车锁系统。系统集成了GPS定位模块、ADXL345加速度传感器、4G通信模块(Air780E)、OLED显示屏、继电器模拟锁控模块等硬件,通过姿态感知实现车辆异常移动检测,在锁车状态下自动触发蜂鸣器报警并通过短信与APP通知用户。

868

WebSocket技术详解:从协议原理到实战应用

WebSocket作为HTML5规范中的重要协议,实现了在单个TCP连接上的全双工通信,彻底改变了传统Web应用的实时交互方式。其核心技术原理包括协议升级握手、二进制帧结构和心跳保活机制,相比HTTP轮询能显著降低网络开销和延迟。在工程实践中,WebSocket广泛应用于在线客服、实时数据监控、协同编辑等场景,通过持久化连接实现毫秒级的消息推送。现代浏览器原生支持WebSocket API,而Spring Boot等框架则提供了完善的服务端实现方案。针对生产环境需求,还需要考虑负载均衡、安全防护和性能优化等

weixin_34258838的博客 358

(10)三相三绕组变压器的建模仿真

建立了三相三绕组变压器组的Simulink仿真模型,通过实例进行了仿真计算。

weixin_45670943的博客 1144

基于规则引擎与SSE的网络故障智能诊断系统设计与实现

网络故障诊断是IT运维中的基础且关键的环节,其核心在于系统性地理解网络分层模型(从物理层到应用层)并执行有序的探测。传统依赖单一Ping命令的手动排查方式效率低下,且难以应对复杂的网络环境。通过引入规则引擎技术,可以将网络工程师的专家经验转化为可执行的、模块化的诊断逻辑,实现故障的自动化推理与定位。结合SSE(Server-Sent Events)协议,能够为诊断过程提供实时、流式的反馈,极大地提升了运维透明度和用户体验。本文聚焦于如何利用Drools规则引擎构建一个分层、可扩展的诊断大脑,并深入解析了Pi

weixin_33970449的博客 441

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

CnOpenData 线上招聘网站信息数据

CnOpenData线上招聘网站信息数据库是一个覆盖中国主流招聘平台、时间跨度长、更新频率高的劳动力市场需求侧大数据集合。本数据库汇集了,为学术界和业界提供了一扇实时观察中国劳动力市场动态的窗口。

CnOpenData_wj的博客 2641

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

手机浏览器或安卓移动端连接 tomcat 的设置方法

一. 手机浏览器 连接 PC Tomcat服务器的方法: 1. 设置PC端的防火墙,参考:http://blog.youkuaiyun.com/chendc201/article/details/22905489 2. 手机和 PC在一个局域网下的同一个网段 3. 直接访问 http://192.168.14.24:8080测试 二.使用安卓模拟器,访问本地 Tomcat,HTTP 报错: exception = failed to connect to /127.0.0.1 (port 808...

tfish的专栏 747

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java携带证书访问Https,Keytool+Tomcat实现SSL双向认证

Keytool+Tomcat实现SSL双向认证 一、SSL简单介绍 参考博客:Https单向认证和双向认证 SSL(Secure Sockets Layer 安全套接层)就是一种协议(规范),用于保障客户端和服务器端通信的安全,以免通信时传输的信息被窃取或者修改。 怎样保障数据传输安全? 客户端和服务器端在进行握手(客户端和服务器建立连接和交换参数的过程称之为握手)时会产生一个“对话密钥”(session key),用来加密接下来的数据传输,解密时也是用的这个“对话密钥”,而这个“对话密钥”只有客户端和

weixin_44480960的博客 3852

Tomcat服务器配置https双向认证(使用keytool生成证书)

一,HTTPS原理 1,HTTP、HTTPS、SSL、TLS介绍与相互关系 (1)HTTP:平时浏览网页时候使用的一种协议。HTTP协议传输的数据都是未加密的(明文),因此使用HTTP协议传输隐私信息非常不安全。 (2)HTTPS:为了保证隐私数据能加密传输,采用SSL/TLS协议用于对...

chensibin3381的博客 442

tomcat实现https双向认证配置

Tomcat实现https双向认证配置1.生成根证书2根证书jks转p123.根证书导出cer文件4.生成客户端的证书库5.生成客户端p12,cer文件6.创建服务器端文件7.使用服务器证书生成认证请求8.使用根证书进行认证9.服务器证书库导入认证后的证书10客户端发起请求 注意:本文偏重于实际操作,理论部分请自行掌握。 注意:所有的代码不可换行,在命令提示符中一行完成。 环境:window 7 ...

a18792721831的博客 7301

java生成和读取keystore_java-如何以编程方式创建新的KeyStore?

java-如何以编程方式创建新的KeyStore?我正在尝试以编程方式在Java中创建新的密钥库。 如下代码:KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());keyStore.setCertificateEntry("alias", cert);引发未初始化的KeyStore异常。Καrτhικ asked 2...

weixin_39825941的博客 865
上一篇: Android RecyclerView嵌套EditView实时更新Item数据
下一篇: Nginx ssl双向认证包含移动端和PC端证书生成
Angus博客
Angus博客 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄12年 557粉丝 282原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值