如何读取RSA私钥文件并按块分词,获取字段对应的完整多行值块
解决方案
核心问题原因
你当前的拆分逻辑有本质缺陷:strtok_r 是无状态的盲切,碰到换行、空格就直接截断,完全不感知RSA私钥文本的字段结构——多行十六进制值本身就是用换行分隔的,自然会被拆成多个单行token,不可能拿到完整字段块。
实现思路
放弃直接全量切割的方案,改为先识别字段边界,再聚合值内容的两步逻辑,适配绝大多数RSA私钥dump的文本格式(字段名行以冒号结尾,后续多行值带统一前导缩进):
- 逐行读取文件内容,先去掉每行首尾的空白字符
- 识别行类型:
- 若行内包含冒号,且冒号后无有效非空白内容:判定为新字段开始,记录当前字段名,重置值缓存
- 若行存在前导缩进/无字段名冒号:判定为上一个字段的值内容,将该行的十六进制字符过滤掉空格、冒号、换行后拼接到当前值缓存中
- 遍历完全部行后,每个字段就对应了聚合完成的完整十六进制值
示例代码(C语言)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define MAX_FIELD_NAME 64 #define LINE_BUF_SIZE 1024 // 字段结构体,存储字段名和对应的完整十六进制值 typedef struct { char name[MAX_FIELD_NAME]; char *value; size_t value_len; } RsaField; int main() { FILE *fp = fopen("privateKey.txt", "r"); if (!fp) { perror("fopen failed"); return -1; } char line_buf[LINE_BUF_SIZE]; RsaField current_field = {0}; size_t field_count = 0; while (fgets(line_buf, LINE_BUF_SIZE, fp) != NULL) { // 跳过空行 char *p = line_buf; while (isspace(*p)) p++; if (*p == '\0') continue; // 查找冒号位置判断是否为字段行 char *colon_pos = strchr(p, ':'); if (colon_pos && (*(colon_pos + 1) == '\0' || isspace(*(colon_pos + 1)))) { // 新字段开始,先输出上一个字段的结果(如果有) if (current_field.value) { printf("字段名:%s\n值:%s\n\n", current_field.name, current_field.value); free(current_field.value); memset(¤t_field, 0, sizeof(RsaField)); field_count++; } // 复制字段名 size_t name_len = colon_pos - p; if (name_len >= MAX_FIELD_NAME) name_len = MAX_FIELD_NAME - 1; strncpy(current_field.name, p, name_len); current_field.name[name_len] = '\0'; } else { // 是值行,只保留十六进制字符,自动过滤空格、冒号、换行 for (char *c = p; *c != '\0'; c++) { if (isxdigit(*c)) { current_field.value = realloc(current_field.value, current_field.value_len + 2); current_field.value[current_field.value_len++] = *c; current_field.value[current_field.value_len] = '\0'; } } } } // 输出最后一个字段 if (current_field.value) { printf("字段名:%s\n值:%s\n\n", current_field.name, current_field.value); free(current_field.value); field_count++; } fclose(fp); printf("共解析到%zu个字段\n", field_count); return 0; }
可选优化
如果你一定要用strtok_r实现,可以调整分隔符优先级:
- 第一级用连续两个换行(空行)作为分隔符,先把整个文件拆成独立的字段块,每个块包含一个字段名和对应的所有值行
- 再对每个字段块单独拆分字段名和值,此时块内的换行不会被提前截断
如果你的私钥是标准PEM格式,更建议直接调用openssl的PEM_read_RSAPrivateKey API直接读取结构化数据,不需要手动解析文本,避免出错。
内容的提问来源于stack exchange,提问作者user45698746
相关产品推荐
相关产品推荐

