CERTIFICATE_VERIFY_FAILED,尽管它应该是有效的?

问题描述 投票:0回答:2

你知道为什么 badCertificateCallback 被调用吗?该证书(dart 声称无效)与我设置为受信任的证书完全相同(相等性检查是正确的!)。

import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';

final PEM = new File(
  '../server_keys/cert.pem',
).readAsBytesSync();

Future<http.Response> listDir(String path) async {
  SecurityContext context = new SecurityContext(withTrustedRoots: false);

  context.setTrustedCertificatesBytes(PEM);

  print("context setup");
  final httpClient = HttpClient(context: context);

  httpClient.badCertificateCallback = ((cert, host, port) {
    print("In bad certificate callback.");
    print('Subject: ${cert.subject}');
    print('Issuer: ${cert.issuer}');
    print('Expires: ${cert.endValidity}');
    print('Host: ${host}');
    print('Port: ${port}');
    return String.fromCharCodes(PEM) == cert.pem;
  });

  print("get url");

  final client = IOClient(httpClient);
  print("POSTING");
  return client
      .post(
        Uri.parse('https://127.0.0.1:5000/list'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(<String, String>{
          'path': path,
        }),
      )
      .timeout(const Duration(seconds: 5));
}

void main() async {
  await listDir("admin/user/test").then((response) {
    print(response.body);
  });
  print("finished");
}

此外,这工作得很好:

curl -v --cacert ../server_keys/cert.pem https://127.0.0.1:5000/list

也许你可以给我一个提示。

更多信息:

这是证书:

-----BEGIN CERTIFICATE-----
MIIE0jCCAroCEQCpB3UQ/DdGjoFQykLNzSJcMA0GCSqGSIb3DQEBDQUAMCcxETAP
BgNVBAoMCFhZWkNsb3VkMRIwEAYDVQQDDAkxMjcuMC4wLjEwHhcNMjIwNjE3MTI1
ODM2WhcNMzIwNjE0MTI1ODM2WjAnMREwDwYDVQQKDAhYWVpDbG91ZDESMBAGA1UE
AwwJMTI3LjAuMC4xMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq8Hg
MaLMUzrDFb5SkpkwpT/0uVX0DL7XUEOgo8QPGWHD5OtM4CGbafF3nW0vdjYWXAhr
RUcqaq/NNu5Z715QvZwdR9jeXs/M4cPJ9/em/4AjvrhaQxJd2pvIr/Tajaw/yqOF
Sw7MT01v4Xszd7ImKeDYcwhyZYo5CdwCUj8lCo4cwq4pRUOGGuUXZiYJzIognC6v
E+UT0Lo/zoDebvc6JUXJ43meH8FxYqGkHHEE+vXwoxyxw64C+fglW4sbMfnrYUmr
EfzOL0DHwygFyl6TIZEM8w+5vXIm4vims6lYEtnlVo0eB+Wj6Y0QPhaA3giTcioX
f6tZYdIx2cRXzRaKujG/iJN+U4N2m/kXidJmkl0Uir+H6YerWdGSLWY7saeuR14i
X5VPVH/zenjbjCAWqQUyp9bvphpBERSmhQWrwVOFqdeqIgHOxn81DCFCEnzNLTMH
+svL8lTF1Q0PSiNB4Rf95TpnhjAGEtk24EE/aJw+uDgPaM9XyIYYSzdcCL2t5EL9
CUz8Lc19Iq6TlKsIPnQdDYFetmzSJaWnxNwyvjLGd3uLbF8CJOm8MQEANTOmImLz
ZFlgH/LXxm/gSngcjxIQYW+d8FbrpWu6RBHF43jxOxLZYx16fcTt/QM1cASsIHuI
kcy9sKvzBsStUqMyLRbuKfF/lAOovDuBwvvzIMECAwEAATANBgkqhkiG9w0BAQ0F
AAOCAgEACQR6Sup+hjY3Jz2EDjeVDoWsliDrtwtZ7T+igTrQbeT1gIiaIf4soJjw
RqQsZXMdFDCHsGI7eneI6wM2L03kXu7CSTL04TYDhr/2ykqjolha1KZ4W6oNlxGr
fqPdVsdo/NpyXn3b/XxtrPQnHRfZUN8OrlCn8wG0fNb6BFVEvPajcayuJdgS2qmn
5Umc66D6LqsuODOu+6URdQApFQYI+nAKQinFDUuNLnIpusaF7QG9r/Mf+m1ADNF+
WvBt594u0XSzR5+dXA0V60nfLxcC8YMqDtQ1bmbYukJRQEoarREJawI4OUYutLu2
XulnUM4sqUnbgAthaO8i5kHWp6iYjnX6B0+COyABBLqiyXu6w0nLMQzv9hekDDaN
CvhDf9BOtLrbFRnZJqxWKITxZw9U58yEeBgIXFQviYUL81tcWk8QyOBrocNBohMz
C+SypMIGPL21+Xv87MwMk/ied5J4V0rY93NOC+MDC6mTbJ1EOr/XEs+TxTu8AnDt
0EhjzXlPj4G100fmaP9BHjMPy8ReSy09bzAU4GPs8dAl7x6aNutyi39E7WeUgJNm
Odv4Wz7LwxX3t/cWkgSoKFT5DuDpBlafbI7ACWCjVe5mgd7cx75mv6pMTqJI8fEA
/OW44WN6IaLHyjG8BeHEt1yVld9RbCeyUY7A4cx94wwpD7TfPlI=
-----END CERTIFICATE-----

这是 python Flask 服务器代码(现在使用 localhost):

import os
from flask import Flask, jsonify
import ssl

app = Flask(__name__)

@app.route("/list", methods = ['POST', 'GET'])
def list_route():
    return jsonify(isError= False,
                    message= "Success",
                    statusCode= 200,
                    data={
                        "path": "hihi"
                    }), 200


if __name__ == "__main__":  
    server_keys = {
        "url": "localhost",
        "cert_file": "server_keys/cert.pem",
        "key_file": "server_keys/key.pem",
    }
    os.system("openssl req -x509 -nodes -new -sha256 -days 390 -newkey rsa:4096 -keyout server_keys/key.pem -out server_keys/cert.pem -subj '/C=de/CN=localhost'")
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)    
    context.load_cert_chain(server_keys["cert_file"], server_keys["key_file"])    
    app.run(debug=True, ssl_context=context, host=server_keys["url"], port="5000")

它正在与curl一起使用:

curl -v --cacert ../server_keys/cert.pem https://localhost:5000/list

但对于我来说,dart 仍然不适合(使用 Intel Mac OSX Monetary)。

flutter dart security ssl certificate
2个回答
1
投票

看起来您偶然发现了 Dart 上的一个错误。关于这个确切的问题有一个“悬而未决的问题”。它仅出现在 macOS 上,但在 Windows/Linux/Android 上它可以完美运行... 下面是生成

bash

中密钥的命令。我自己测试了该脚本,它在 Windows 上可以运行,但在 macOS 上失败。

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' -extensions EXT \
  -config <(printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")



0
投票
SecurityContext

的所有内容都已就位,密钥/证书/ca-cert 的格式正确(我正在配置 mTLS),但在 Android 上它可以工作,但在 iOS 上却不能。它失败并出现错误: screenshot of error 经过几天的痛苦,我发现了苹果对可信证书的要求,最终解决了我的问题:

https://support.apple.com/en-au/103769

© www.soinside.com 2019 - 2024. All rights reserved.