域名证书信息查询
接口说明
该接口是一个证书信息查询服务,能够对证书信息进行查询。key_type支持输入类型(cert、domain、serverip、akid、skid、sn、subject_O、raw_cert 之一),val输入查询值,根据不同的查询类型和值,以列表形式返回信息,返回信息包括证书组织、证书主题、签发单位所在国家、签发单位公用名称、有效期开始时间、主体可选名称、签发证书单位名称、等证书相关信息。
具体的请求示例:/sn/6333067948887798706277381429131909282/。
请求地址
https://api.f.360.cn/std/tls_cert/:key_type/:val/
请求方法
GET
请求参数
| 参数名 | 类型 | 位置 | 是否必填 | 示例值 | 说明 |
|---|---|---|---|---|---|
| key_type | String | path | 是 | sn | 查询类型(cert/domain/serverip/akid/skid/spki/sn) |
| val | String | path | 是 | 6333067948887798706277381429131909282 | 查询值 |
| limit | Int | query | 否 | 5 | 响应的最大记录数(默认100) |
| src | String | query | 否 | cert_trans | 子域名scan起始位置,默认为空 |
| lite | String | query | 否 | SAN | 只返回指定字段 |
响应参数
| 名称 | 字段类型 | 示例值 | 描述 |
|---|---|---|---|
| msg | string | ok | 响应状态信息 |
| code | string | 0 | 响应状态码 |
| data | Array(object) | 见下方示例 | 证书数据列表 |
| extendedKeyUsage | - | - | 扩展密钥用途 |
| is_ca | - | - | 是否为CA |
| AKID | - | - | 授权密钥标识 |
| sources | - | - | 数据来源 |
| subject_CN | - | - | 证书主题 |
| first_seen | - | - | 首次发现时间 |
| cert_chain | - | - | 证书链 |
| issuer | - | - | 组织 |
| end | - | - | 有效期结束时间 |
| SAN | - | - | 主体可选名称 |
| crlDistributionPoints | - | - | 证书吊销列表分发点 |
| spki | - | - | 公钥哈希 |
| start | - | - | 有效期开始时间 |
| keyUsage | - | - | 密钥用途 |
| version | - | - | 证书版本信息 |
| certificatePolicies | - | - | 证书策略 |
| life_time | - | - | 生命周期 |
| insert_time | - | - | 入库时间 |
| issuer_C | - | - | 签发单位所在国家 (Country) |
| spki_b64 | - | - | 公钥编码 |
| issuer_CN | - | - | 签发单位公用名称 (Common Name) |
| issuer_O | - | - | 签发证书单位名称 (Organization Name) |
| PKL | - | - | 公钥长度 |
| subject_L | - | - | 所在城市 (Locality) 简称:L 字段 |
| subject_O | - | - | 单位名称 (Organization Name) :简称:O 字段,对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于客户端单位证书则为证书申请者所在单位名称; |
| sec_stat | - | - | 安全状态详情 |
| samples | - | - | 请求证书的样本 |
| cert_type | - | - | 证书类型 |
| subject | - | - | 公用名称 (Common Name) 简称:CN 字段,对于 SSL 证书,一般为网站域名或IP地址;而对于代码签名证书则为申请单位名称;而 对于客户端证书则为证书申请者的姓名; 单位名称 (Organization Name) :简称:O 字段,对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于 客户端单位证书则为证书申请者所在单位名称; 证书申请单位所在地: 所在城市 (Locality) 简称:L 字段 所在省份 (State/Provice) 简称:S 字段 所在国家 (Country) 简称:C 字段,只能是国家字母缩写,如中国:CN 其他一些字段: 电子邮件 (Email) 简称:E 字段 多个姓名字段 简称:G 字段 介绍:Description 字段 电话号码:Phone 字段,格式要求 + 国家区号 城市区号 电话号码,如: +86 732 88888888 地址:STREET 字段 邮政编码:PostalCode 字段 显示其他内容 简称:OU 字段 |
| subject_C | - | - | 所在国家 (Country) 简称:C 字段,只能是国家字母缩写,如中国:CN |
| CT | - | - | 证书透明度 |
| PKA | - | - | 公钥算法 |
| cert_chain_valid | - | - | 证书链是否有效 |
| securityState | - | - | 安全状态 |
| subject_ST | - | - | 主体州/省份 |
| SKID | - | - | 主体密钥标识符 |
| md5 | - | - | 证书哈希md5 |
| sha1 | - | - | 证书哈希sha1 |
| originals | - | - | 证书的来源域名 |
| level | - | - | 证书层级 |
| sha256 | - | - | 证书哈希sha256 |
| SN | - | - | 证书的序列号 |
| err_codes | - | - | 错误码 |
| authorityInfoAccess | - | - | 权威信息访问 |
| SA | - | - | 签名算法 |
| endpoints | - | - | 服务端 |
| last_seen | - | - | 末次发现时间 |
请求示例
支持cUrl、Python、Java、PHP、Go语言的请求,示例如下
#!/usr/bin/env bash
set -euo pipefail
APPID="" # apikey
SECRET="" # salt
URL="https://api.f.360.cn/std/tls_cert/sn/6333067948887798706277381429131909282/"
BODY=""
NONCE=$(printf '%08d' $((RANDOM % 100000000)))
TIMESTAMP=$(date +%s)
BODY_MD5=$(printf '%s' "$BODY" | openssl dgst -md5 -hex | awk '{print $NF}')
SIGNATURE=$(printf '%s' "${BODY_MD5}${APPID}${NONCE}${TIMESTAMP}${SECRET}" | openssl dgst -md5 -hex | awk '{print $NF}')
SIGNATURE=${SIGNATURE:16}
curl --location --request GET "$URL" \
--header "Content-Type: application/json" \
--header "X-360-Key: ${APPID}" \
--header "X-360-Nonce: ${NONCE}" \
--header "X-360-Timestamp: ${TIMESTAMP}" \
--header "X-360-Signature: ${SIGNATURE}"#-*- coding:utf-8 -*—
import requests
import json
import random
import hashlib
import time
APPID = "" # apikey
SECRET = "" # salt
def make_headers(appid, secret, body=""):
headers = {}
headers["X-360-Key"] = appid
headers["X-360-Nonce"] = str(random.randint(0, 99999999)).zfill(8)
headers["X-360-Timestamp"] = str(int(time.time()))
s = (
hashlib.md5(body.encode("utf8")).hexdigest()
+ headers["X-360-Key"]
+ headers["X-360-Nonce"]
+ headers["X-360-Timestamp"]
+ secret
)
md5 = hashlib.md5(s.encode("utf8")).hexdigest()
headers["X-360-Signature"] = md5[16:]
headers["Content-Type"] = "application/json"
return headers
def do_get(url, params):
res = requests.get(url, headers=make_headers(APPID, SECRET), params=params)
print(res.text)
if __name__ == "__main__":
# 请求地址
url = "https://api.f.360.cn/std/tls_cert/sn/6333067948887798706277381429131909282/"
do_get(url, {})import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.concurrent.ThreadLocalRandom;
public class Demo {
static String md5(String input) throws Exception {
byte[] digest = MessageDigest.getInstance("MD5")
.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
String appid = ""; // apikey
String secret = ""; // salt
String url = "https://api.f.360.cn/std/tls_cert/sn/6333067948887798706277381429131909282/";
String body = "";
String nonce = String.format("%08d", ThreadLocalRandom.current().nextInt(100000000));
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
String signature = md5(md5(body) + appid + nonce + timestamp + secret).substring(16);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.header("X-360-Key", appid)
.header("X-360-Nonce", nonce)
.header("X-360-Timestamp", timestamp)
.header("X-360-Signature", signature)
.GET()
.build();
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
System.out.println(response.body());
}
}<?php
// apikey
$appid = "";
// salt
$secret = "";
$url = 'https://api.f.360.cn/std/tls_cert/sn/6333067948887798706277381429131909282/';
$body = "";
$nonce = str_pad((string) random_int(0, 99999999), 8, "0", STR_PAD_LEFT);
$timestamp = (string) time();
$signature = substr(md5(md5($body) . $appid . $nonce . $timestamp . $secret), 16);
$ch = curl_init($url);
$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-360-Key: {$appid}",
"X-360-Nonce: {$nonce}",
"X-360-Timestamp: {$timestamp}",
"X-360-Signature: {$signature}",
],
];
$options[CURLOPT_HTTPGET] = true;
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
if ($response === false) {
echo curl_error($ch), PHP_EOL;
} else {
echo $response, PHP_EOL;
}
curl_close($ch);package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"math/rand"
"net/http"
"time"
)
func md5Hex(s string) string {
sum := md5.Sum([]byte(s))
return hex.EncodeToString(sum[:])
}
func main() {
appid := "" // apikey
secret := "" // salt
url := "https://api.f.360.cn/std/tls_cert/sn/6333067948887798706277381429131909282/"
body := []byte("")
nonce := fmt.Sprintf("%08d", rand.Intn(100000000))
timestamp := fmt.Sprintf("%d", time.Now().Unix())
signature := md5Hex(md5Hex(string(body)) + appid + nonce + timestamp + secret)[16:]
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-360-Key", appid)
req.Header.Set("X-360-Nonce", nonce)
req.Header.Set("X-360-Timestamp", timestamp)
req.Header.Set("X-360-Signature", signature)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(respBody))
}响应示例
业务正常响应
{
"msg": "ok",
"code": "0",
"data": [
{
"extendedKeyUsage": "TLS Web Server Authentication, TLS Web Client Authentication",
"is_ca": false,
"AKID": "24:6F:91:3F:89:87:87:0E:32:C2:40:18:DF:C5:4C:EB:4F:C8:49:32",
"subject_CN": "*.163.com",
"first_seen": 1679568509,
"cert_chain": [
"7df1c5f3c9469a05bf61d564c5202f20eee07210",
"a8985d3a65e5e5c4b2d7d66d40c6dd2fb19c5436"
],
"issuer": "C=US, O=DigiCert Inc, CN=GeoTrust RSA CN CA G2",
"end": 1713801599,
"SAN": [
"*.163.com",
"163.com"
],
"crlDistributionPoints": "\nFull Name:\n URI:http://crl.digicert.cn/GeoTrustRSACNCAG2.crl\n",
"keyUsage": "Digital Signature, Key Encipherment",
"spki": "4ae3d068896a9b03abe2dcb1cfa343b2dab09af143a52bbbcaa7fd974a276764",
"start": 1679500800,
"cert_C": "CN",
"version": "0x2",
"certificatePolicies": "Policy: 2.23.140.1.2.2\n CPS: http://www.digicert.com/CPS\n",
"insert_time": 1698533950,
"issuer_C": "US",
"spki_b64": "SuPQaIlqmwOr4tyxz6NDstqwmvFDpSu7yqf9l0onZ2Q=",
"issuer_CN": "GeoTrust RSA CN CA G2",
"life_time": 34300799.0,
"PKL": 2048,
"subject_L": "hangzhou",
"subject_O": "NetEase (Hangzhou) Network Co., Ltd",
"sec_stat": [],
"samples": [],
"cert_type": "OV",
"subject": "C=CN, ST=zhejiang, L=hangzhou, O=NetEase (Hangzhou) Network Co., Ltd, CN=*.163.com",
"subject_C": "CN",
"CT": true,
"PKA": "rsaEncryption",
"cert_chain_valid": "True",
"securityState": "secure",
"subject_ST": "zhejiang",
"SKID": "3D:47:C9:16:09:E6:3A:A4:BD:82:FB:0B:A4:D2:B7:CF:F2:DD:EE:E1",
"md5": "15172dee123eaf6df59c0ca62c140296",
"sha1": "a9c98fa15769de65b1f605f2ba6b8f256888f220",
"originals": [
"myl.163.com",
"hz.163.com"
],
"level": [
"leaf"
],
"issuer_O": "DigiCert Inc",
"sha256": "c9a2c86933047a6d48dbd96a7b007a785ae8c48ec0d26017f99d964240a174d5",
"SN": "6333067948887798706277381429131909282",
"err_codes": [
"AUTHORITY_INVALID",
"INVALID",
"REVOKED"
],
"authorityInfoAccess": "OCSP - URI:http://ocsp.digicert.cn\nCA Issuers - URI:http://cacerts.digicert.cn/GeoTrustRSACNCAG2.crt\n",
"SA": "sha256WithRSAEncryption",
"endpoints": [
"",
"42.186.175.13:443",
"42.186.192.23:443"
],
"basicConstraints": "CA:FALSE",
"last_seen": 1698509332
}
]
}key:serverip 格式正常响应示例
{
"msg": "ok",
"code": "0",
"data": [
{
"sha1": "eff12bfdf737dc16d2da24177a7999f122913f01",
"cert_chain_valid": "unknown",
"insert_time": 1698616641,
"ip_int": 2130706433,
"first_seen": 1696695833,
"port": 443,
"last_seen": 1698579166
}
]
}业务异常响应
{
"code": "GT00201",
"msg": "服务请求异常:xxxx"
}