AES-256解密脚本遇jq错误:Cannot index string with string 'files'
问题根源分析与解决方法
错误信息
执行解密脚本时触发以下jq错误:
jq: error (at <stdin>:7): Cannot index string with string "files"
原加密脚本(生成JSON并AES-256加密)
#!/bin/bash #Note: This script will require an installation of jq to operate correctly # Check whether the user has provided correct inputs if [ "$1" = "" ] || [ "$2" = "" ]; then echo "Error – Please pass two parameters: a specific text document and the contents of a folder as inputs to the script" exit 1 fi # Set source text document and folder name TEXT_DOC="$1" FOLDER="$2" # Create an empty JSON-formatted template store echo "{}" > template.json # Read text document into array IFS=$'\n' text=("$(<$TEXT_DOC)") # Loop through text document and populate template array for var in "${text[@]}"; do key=$(echo "$var" | cut -f1 -d";" ) value=$(echo "$var" | cut -f2 -d";" ) jq --arg key "$key" --arg value "$value" '. + {($key): ($value)}' template.json > template_temp.json mv template_temp.json template.json done # Loop through folder and add it's contents to the template array for FILE in `find $FOLDER -type f`; do content=$(<$FILE) filename=$(echo "$FILE" | cut -f2 -d"/") jq --arg filename "$filename" --arg content "$content" '. + {($filename): ($content)}' template.json > template_temp.json mv template_temp.json template.json done # Encrypt the template array with AES-256 openssl aes-256-cbc -a -salt -pbkdf2 -in template.json -out "${FOLDER%?}.enc" # Remove plain text template array rm template.json echo "JSON-formatted template store successfully encrypted with AES-256"
出错的反向解密脚本
#!/bin/bash set -x # This script will decrypt the given AES-256 encrypted file and output the contained files into the given Output_folder directory # Read the encrypted file and store it in a variable fileToDecrypt="$1" outputDir="Output_folder" # Create the output directory if it does not exist if [ ! -d "$outputDir" ] then mkdir $outputDir fi # Decrypt the given encrypted file and save the content in the output directory openssl aes-256-cbc -d -a -pbkdf2 -in $fileToDecrypt -out "$outputDir/decrypted_file.json" # Extract each file stored in the decrypted json content and save it to output directory cat "$outputDir/decrypted_file.json" | jq -r '.[] | .files[] | "\(.name)"' | while read file ; do echo "Extracting decrypted_file.json to directory $outputDir" cp "$file" "$outputDir" done
解密后的JSON内容
{ "fake yaml file\r": "fake yaml file\r", "Fakefile1.txt": "Fakecontents1=stuff1\r\nFakecontents2=stuff2\r\nFakecontents3=stuff3\r\nFakecontents4\r\nFakecontents5\r\nFakecontents6", "Fakefile2.txt": "Fakecontents1=stuff1\r\nFakecontents2=stuff2\r\nFakecontents3=stuff3\r\nFakecontents4\r\nFakecontents5\r\nFakecontents6", "Fakefile3.txt": "Fakecontents1=stuff1\r\nFakecontents2=stuff2\r\nFakecontents3=stuff3\r\nFakecontents4\r\nFakecontents5\r\nFakecontents6", "Fakefile4.txt": "Fakecontents1=stuff1\r\nFakecontents2=stuff2\r\nFakecontents3=stuff3\r\nFakecontents4\r\nFakecontents5\r\nFakecontents6" }
期望恢复的文件结构
├── Output_folder | └── azure-pipelines.yaml | └── Config-Store │ └── Fakefile1.txt │ └── Fakefile2.txt │ └── Fakefile3.txt │ └── Fakefile4.txt
问题根源
- 解密脚本jq逻辑完全错误:
解密后的JSON是扁平键值对结构(键为文件名、值为文件内容),但解密脚本里的jq命令.[] | .files[]试图从字符串类型的文件内容中索引.files字段,完全不符合实际JSON结构,直接触发报错。 - 原加密脚本存在逻辑缺陷:
- 文本文件键值映射错误:解密后的JSON第一个键是内容
fake yaml file\r,而非期望的文件名azure-pipelines.yaml,说明原脚本把文本文件的键值搞反,或文本文件格式不符合目标文件名;文件内容的预期。 - 丢失目录结构:处理文件夹时用
cut -f2 -d"/"只提取文件名,未保留Config-Store/相对路径,导致解密后无法重建子目录。
- 文本文件键值映射错误:解密后的JSON第一个键是内容
解决方法
第一步:修复解密脚本
修改jq逻辑,遍历JSON键值对,创建对应文件(含子目录)并写入内容:
#!/bin/bash set -x fileToDecrypt="$1" outputDir="Output_folder" # 创建输出目录(含子目录) mkdir -p "$outputDir/Config-Store" # 解密文件 openssl aes-256-cbc -d -a -pbkdf2 -in "$fileToDecrypt" -out "$outputDir/decrypted_file.json" # 遍历JSON键值对生成文件 cat "$outputDir/decrypted_file.json" | jq -r 'to_entries[] | "\(.key)\t\(.value)"' | while IFS=$'\t' read -r filename content; do # 去除Windows回车符 filename=$(echo "$filename" | tr -d '\r') content=$(echo "$content" | tr -d '\r') # 匹配yaml文件并生成目标文件 if [[ "$filename" == "fake yaml file" ]]; then echo -e "$content" > "$outputDir/azure-pipelines.yaml" echo "生成文件:$outputDir/azure-pipelines.yaml" # 匹配Fakefile系列,写入Config-Store子目录 elif [[ "$filename" == Fakefile* ]]; then echo -e "$content" > "$outputDir/Config-Store/$filename" echo "生成文件:$outputDir/Config-Store/$filename" fi done # 清理临时JSON文件(可选) rm "$outputDir/decrypted_file.json"
第二步:修复原加密脚本
修正文本文件键值映射,保留文件夹相对路径:
#!/bin/bash # 需要安装jq if [ "$1" = "" ] || [ "$2" = "" ]; then echo "错误:请传入两个参数:文本文件路径 和 文件夹路径" exit 1 fi TEXT_DOC="$1" FOLDER="$2" echo "{}" > template.json # 处理文本文件:键为目标文件名,值为内容(预期文本文件每行格式:目标文件名;文件内容) IFS=$'\n' for var in $(<$TEXT_DOC); do # 去除Windows回车符 var=$(echo "$var" | tr -d '\r') filename=$(echo "$var" | cut -f1 -d";") content=$(echo "$var" | cut -f2- -d";") jq --arg fn "$filename" --arg ct "$content" '. + {($fn): ($ct)}' template.json > temp.json mv temp.json template.json done # 处理文件夹:保留相对路径(如Config-Store/Fakefile1.txt) for FILE in $(find "$FOLDER" -type f); do # 获取相对于上级目录的路径 rel_path=$(realpath --relative-to="$FOLDER/.." "$FILE") content=$(cat "$FILE" | tr -d '\r') # 去除Windows回车符 jq --arg rp "$rel_path" --arg ct "$content" '. + {($rp): ($ct)}' template.json > temp.json mv temp.json template.json done # 加密生成文件 openssl aes-256-cbc -a -salt -pbkdf2 -in template.json -out "${FOLDER}.enc" rm template.json echo "JSON已加密为${FOLDER}.enc"
内容的提问来源于stack exchange,提问作者Akira_Yam
相关产品推荐
相关产品推荐

