江苏医保网络查询实现分析.md 8.1 KB

江苏医保HeaSecReadInfo.dll网络查询实现机制分析

🌐 网络查询的完整流程

第一步:初始化时的网络配置

// 我们调用的初始化
Init(jsonConfig, errMsg);

// DLL内部可能的实现逻辑:
internal class NetworkManager 
{
    private string serverUrl;      // http://10.61.165.3:8086
    private string csbApiName;     // hssServives
    private string accessKey;      // a94971b5ecee4bb994bce25c9291ccbf
    private string secretKey;      // 3ni3n+nWhGCsiu6SITGUqNfzvx8=
    private string orgId;          // H32132200561
    private string areaCode;       // 321322
    
    public bool Initialize(JiangSuConfig config)
    {
        // 1. 建立HTTP连接池
        this.httpClient = new HttpClient();
        this.httpClient.BaseAddress = new Uri($"http://{config.IP}:{config.PORT}");
        this.httpClient.Timeout = TimeSpan.FromSeconds(config.TIMEOUT);
        
        // 2. 配置CSB认证
        this.csbAuthenticator = new CSBAuthenticator(config.ACCESS_KEY, config.SECRETKEY);
        
        // 3. 测试连接
        return TestConnection();
    }
}

第二步:读卡时的网络查询

// 我们调用的读卡函数
ReadCardBas(cardInfo, busiCardInfo);

// DLL内部可能的网络查询实现:
internal int ReadCardBasInternal(StringBuilder cardInfo, StringBuilder busiCardInfo)
{
    try 
    {
        // 1. 硬件读取社保卡基础标识
        string cardId = ReadCardPhysicalId();  // 读取卡号
        string idNumber = ReadCardIdNumber();  // 读取身份证号
        
        // 2. 构造网络查询请求
        var queryRequest = new 
        {
            cardId = cardId,
            idNumber = idNumber,
            orgId = this.orgId,           // H32132200561
            areaCode = this.areaCode,     // 321322
            businessType = "socialcard",
            timestamp = DateTime.Now.ToString("yyyyMMddHHmmss")
        };
        
        // 3. CSB服务总线认证
        var headers = GenerateCSBHeaders(queryRequest);
        
        // 4. 发送网络请求到医保中心
        var response = await PostToMedicalCenter(queryRequest, headers);
        
        // 5. 解析返回的医保数据
        var medicalData = ParseMedicalCenterResponse(response);
        
        // 6. 格式化为38号文标准格式
        string formatted38Data = FormatTo38Document(medicalData);
        
        // 7. 填充输出缓冲区
        cardInfo.Append(formatted38Data);
        busiCardInfo.Append(medicalData.BusinessInfo);
        
        return 0; // 成功
    }
    catch (NetworkException ex)
    {
        LogError($"网络查询失败: {ex.Message}");
        return -1; // 网络错误
    }
    catch (AuthenticationException ex)
    {
        LogError($"CSB认证失败: {ex.Message}");
        return -2; // 认证错误
    }
}

// CSB服务总线认证头生成
private Dictionary<string, string> GenerateCSBHeaders(object request)
{
    var headers = new Dictionary<string, string>();
    
    // CSB标准认证头
    headers["_api_name"] = this.csbApiName;        // hssServives
    headers["_api_version"] = "1.0.0";
    headers["_api_access_key"] = this.accessKey;   // a94971b5ecee4bb994bce25c9291ccbf
    
    // 生成签名
    string requestBody = JsonConvert.SerializeObject(request);
    string signature = GenerateHMACSignature(requestBody, this.secretKey);
    headers["_api_signature"] = signature;
    
    // 时间戳
    headers["_api_timestamp"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
    
    return headers;
}

// 网络请求到医保中心
private async Task<string> PostToMedicalCenter(object request, Dictionary<string, string> headers)
{
    var httpRequest = new HttpRequestMessage(HttpMethod.Post, "/api/socialcard/query");
    
    // 添加CSB认证头
    foreach (var header in headers)
    {
        httpRequest.Headers.Add(header.Key, header.Value);
    }
    
    // 请求体
    string jsonBody = JsonConvert.SerializeObject(request);
    httpRequest.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
    
    // 发送请求
    var response = await this.httpClient.SendAsync(httpRequest);
    
    if (response.IsSuccessStatusCode)
    {
        return await response.Content.ReadAsStringAsync();
    }
    else
    {
        throw new NetworkException($"HTTP {response.StatusCode}: {response.ReasonPhrase}");
    }
}

第三步:数据格式转换

// 将医保中心返回的JSON数据转换为38号文格式
private string FormatTo38Document(MedicalCenterResponse data)
{
    // 38号文标准格式:11个字段用|分隔
    var fields = new string[]
    {
        data.PersonalNumber,     // 个人编号
        data.Name,               // 姓名
        data.Gender,             // 性别
        data.Nation,             // 民族
        data.Birthday,           // 出生日期
        data.IdNumber,           // 身份证号
        data.Address,            // 地址
        data.IssueDate,          // 发卡日期
        data.ValidDate,          // 有效期
        data.CardNumber,         // 卡号
        data.Photo               // 照片(Base64)
    };
    
    return string.Join("|", fields);
}

🔑 关键网络组件

1. CSB服务总线认证

POST /api/socialcard/query HTTP/1.1
Host: 10.61.165.3:8086
Content-Type: application/json
_api_name: hssServives
_api_version: 1.0.0
_api_access_key: a94971b5ecee4bb994bce25c9291ccbf
_api_signature: [HMAC-SHA256签名]
_api_timestamp: 1703123456

{
  "cardId": "D156000012345678",
  "idNumber": "320123199001011234",
  "orgId": "H32132200561",
  "areaCode": "321322",
  "businessType": "socialcard"
}

2. 医保中心响应

{
  "code": "0000",
  "message": "查询成功",
  "data": {
    "personalNumber": "320123199001011234",
    "name": "张三",
    "gender": "1",
    "nation": "01",
    "birthday": "19900101",
    "idNumber": "320123199001011234",
    "address": "江苏省宿迁市沭阳县...",
    "issueDate": "20200101",
    "validDate": "20301231",
    "cardNumber": "D156000012345678",
    "photo": "base64编码的照片数据",
    "insuranceStatus": "正常",
    "accountBalance": "1234.56"
  }
}

📊 网络查询时序图

用户程序          我们的代码         HeaSecReadInfo.dll    CSB服务总线      医保中心数据库
    |                |                    |                |                |
    |--ReadCard----->|                    |                |                |
    |                |--ReadCardBas------>|                |                |
    |                |                    |--读取卡片标识--->|                |
    |                |                    |                |                |
    |                |                    |--构造查询请求--->|                |
    |                |                    |                |--CSB认证------->|
    |                |                    |                |                |
    |                |                    |                |--查询个人信息--->|
    |                |                    |                |<--返回完整数据---|
    |                |                    |<--JSON响应------|                |
    |                |                    |                |                |
    |                |                    |--格式化38号文--->|                |
    |                |<--38号文格式数据----|                |                |
    |<--JSON结果------|                    |                |                |

🎯 总结

江苏医保的 HeaSecReadInfo.dll 网络查询实现的核心特点:

  1. 混合读取:卡片提供身份标识,网络获取完整信息
  2. CSB认证:使用企业服务总线进行安全认证
  3. 标准化输出:将网络数据格式化为38号文标准格式
  4. 实时查询:每次读卡都会实时查询最新的医保信息
  5. 多重验证:卡片验证 + 网络验证 + CSB认证

这就是为什么江苏医保需要13个复杂参数的原因 - 它需要完整的网络连接、认证和数据交换配置!