You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

API加密文档下载及解密异常问题咨询

需求与问题汇总

需求:从API获取加密文档,解密后保存为本地字符串,不使用Blob,仅通过临时缓存文件实现。计划流程:获取API返回的二进制文档数据 → 转换为字节数组 → 转为FileStream处理。


问题1:文件路径含非法字符异常

下载API数据的代码实现

private static byte[] data;
                   
public static byte[] Download(List<Document> documents)       
{       
    Download download = new Download();          
     
    foreach (Document document in documents)           
    {                        
        if (document.file_ != null)              
        {            
            using (var client = new RestClient(uri))                
            {                    
                try                      
                {  
                    RestRequest request = new RestRequest(document.file_, Method.Get);  
        
                    request.Timeout = -1;                                   
                    request.AddHeader("Content-Type_", "application/json");                                        
                    var body = @"{
                        ""justices"": [
                            { ""number"": ""24303016000131"" } 
                        ] 
                    }";                    
        
                    request.AddParameter("application/json", body, ParameterType.RequestBody);         
        
                    RestResponse response = client.Execute(request);                                        
                    var ret = response.Content;                                      
                    data = ASCIIEncoding.UTF8.GetBytes(ret);               
                    download.binary = data; 
                }  
                catch (Exception ex)
                {
                    throw ex;   // 抛出异常:System.ArgumentException: 'Illegal characters in path. (Parameter 'path')'
                }
            }
        }
    }
    return download.binary;
}

模型定义

public class Download
{
    public byte[] binary { get; set; }
}

字节数组转文件的代码及异常

调用以下方法时抛出异常:Message = Illegal characters in path. (Parameter 'path')

public static bool ByteArrayToFile(string fileName, byte[] byteArray)
{ 
    try 
    { 
        using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
        { 
            fs.Write(byteArray, 0, byteArray.Length); 
            return true; 
        } 
    } 
    catch (Exception ex) 
    { 
        Console.WriteLine("Exception caught in process: {0}", ex); 
    } 
   
    return false;
}

修复方案

  • 修正请求Header的笔误:将Content-Type_改为标准的Content-Type,避免API解析请求出错。
  • 检查并修正文件路径:确保传入ByteArrayToFile的fileName不含非法字符(如/ \ : * ? " < > |等),可通过Path.GetInvalidPathChars()识别并替换非法字符;推荐用Path.GetTempFileName()或Path.Combine(Path.GetTempPath(), "temp_doc.bin")生成合法临时文件路径,避免手动拼接出错。
  • 正确获取二进制数据:若API返回的是二进制流,应直接使用response.RawBytes获取字节数组,而非将response.Content(字符串)转ASCII字节数组——ASCII编码会丢失非ASCII字节数据,导致后续解密失败。

问题2:解密算法的密钥尺寸不合法异常

解密代码实现

调用该方法时抛出异常:System.Security.Cryptography.CryptographicException: 'Specified key is not a valid size for this algorithm.'

public static void Decrypt(byte[] downloadDoc)  
{  
    if (downloadDoc == null) 
        throw new ArgumentNullException(nameof(downloadDoc)); 
    else if (downloadDoc.Length == 0) 
        throw new ArgumentOutOfRangeException(nameof(downloadDoc));
           
    BinaryFormatter formatter = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    
    formatter.Serialize(ms, downloadDoc);
    var rt = Convert.ToBase64String(ms.ToArray());
      
    using (var rijndaelManaged = new RijndaelManaged())
    {
        rijndaelManaged.KeySize = (rt.Length / 8) * 2;
        rijndaelManaged.Key = downloadDoc;
        rijndaelManaged.BlockSize = (rt.Length / 8) * 2;        

        using (var decryptor = rijndaelManaged.CreateDecryptor())
        using (var cryptoStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
        {
            var decrypted = new byte[downloadDoc.Length];
            var bytesRead = cryptoStream.Read(decrypted, 0, downloadDoc.Length);
    
            var ret = decrypted.Take(bytesRead).ToArray();
        }
    }
}

修复方案

  • 遵循Rijndael尺寸规范:Rijndael的合法KeySize为128/192/256位,BlockSize为128/192/256位,需确认API加密时使用的参数,设置对应合法值(如常用的256位密钥对应32字节),不能随意通过字符串长度计算。
  • 区分加密文档与密钥:downloadDoc是加密后的文档内容,不能直接作为解密密钥使用,需单独获取加密时使用的密钥(固定密钥或API返回的密钥参数),并将密钥转换为符合尺寸要求的字节数组。
  • 移除冗余的序列化逻辑:BinaryFormatter.Serialize序列化字节数组完全多余,直接使用原始downloadDoc即可,无需转Base64再计算尺寸。
  • 修正MemoryStream指针位置:序列化后ms的指针处于流末尾,需先调用ms.Seek(0, SeekOrigin.Begin)将指针移到开头,否则CryptoStream无法读取数据。

内容的提问来源于stack exchange,提问作者Caroline Sousa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 22:16:16