You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP连接MySQL时Android端SSL证书缺失:创建与配置方法问询

解决Android调用PHP HTTPS接口时的SSLHandshakeException错误

一、先搞清楚:给哪配证书?

这个错误是Android和运行PHP的Web服务器(Apache/Nginx这类)建立HTTPS连接时,不信任服务器的SSL证书导致的,和MySQL数据库半毛钱关系都没有——PHP和MySQL的SSL连接是后端内部的事,Android根本管不着。你要做的是给Web服务器配SSL证书,让Android认它。

二、生成自签名证书(测试环境用)

生产环境建议用正规CA签发的免费证书(比如Let's Encrypt),测试环境自己用OpenSSL生成就行:

  1. 确保你装了OpenSSL(Linux基本自带,Windows自己下OpenSSL工具包)
  2. 依次跑这三条命令:
    • 生成服务器私钥:
      openssl genrsa -out server.key 2048
      
    • 生成证书签名请求(按提示填信息,Common Name必须填你的服务器IP/域名,比如你用的127.0.0.1):
      openssl req -new -key server.key -out server.csr
      
    • 生成自签名证书(有效期365天):
      openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
      

三、给Web服务器配置HTTPS

1. Apache配置

  • 找到Apache的SSL配置文件(一般叫httpd-ssl.conf或ssl.conf)
  • 加这几行配置:
    SSLEngine on
    SSLCertificateFile /你放证书的路径/server.crt
    SSLCertificateKeyFile /你放私钥的路径/server.key
    
  • 启用SSL模块(Linux跑a2enmod ssl),然后重启Apache。

2. Nginx配置

  • 打开你的站点配置文件(比如/etc/nginx/sites-available/你的项目.conf)
  • 加一个HTTPS的server块:
    server {
        listen 443 ssl;
        server_name 127.0.0.1;  # 必须和证书的Common Name一致
    
        ssl_certificate /你放证书的路径/server.crt;
        ssl_certificate_key /你放私钥的路径/server.key;
    
        # 下面是你的项目基础配置,比如PHP解析
        root /你的PHP项目根目录;
        location ~ \.php$ {
            fastcgi_pass unix:/run/php/php7.4-fpm.sock;  # 按你的PHP版本改
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
    
  • 重启Nginx生效。

四、Android端怎么处理证书?

方法1:把证书放进项目,让Android信任它(推荐)

  1. 把生成的server.crt重命名为server.cer,放到Android项目的app/src/main/res/raw目录(没有raw目录就自己建一个)。
  2. 写个工具类生成自定义的SSLSocketFactory:
    import android.content.Context;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.cert.CertificateFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManagerFactory;
    
    public class SSLUtils {
        public static SSLSocketFactory getSSLSocketFactory(Context context) {
            try {
                CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
                InputStream certStream = context.getResources().openRawResource(R.raw.server);
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(null);
                keyStore.setCertificateEntry("server", certFactory.generateCertificate(certStream));
    
                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                trustManagerFactory.init(keyStore);
    
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
                return sslContext.getSocketFactory();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    
  3. 修改你的PutData类,让它用这个自定义的SSLSocketFactory。假设PutData里用的是HttpURLConnection,找到打开连接的地方,改成:
    HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection();
    httpsConn.setSSLSocketFactory(SSLUtils.getSSLSocketFactory(你的Context实例)); // 比如传Activity.this
    

方法2:测试环境临时跳过SSL验证(别放生产!)

如果只是临时测试,不想搞证书信任的话,可以直接绕过SSL检查,但生产环境绝对不能这么干:

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class SSLSkipUtils {
    public static void disableSSLCheck() {
        try {
            TrustManager[] trustAll = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() { return null; }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                }
            };

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAll, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在调用putData.startPut()之前,先跑SSLSkipUtils.disableSSLCheck();就行。

内容的提问来源于stack exchange,提问作者user21655182

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:55:01