C#实现PGP解密时提示路径访问被拒绝,无法创建输出文件怎么办
问题根因与修复方案
核心错误点
你传入Decrypt方法的第四个参数是目录路径D:\Decryption\Output,但在未触发签名校验的else分支中,你没有拼接解密后的文件名,直接把目录路径传给File.Create(),系统不允许创建和已存在目录同名的文件,直接触发权限拒绝报错。
其他潜在问题
- 你拼接文件名的逻辑里没有加路径分隔符,比如
outputFile是D:\Decryption\Output,直接拼test.txt会变成D:\Decryption\Outputtest.txt,根本不会写到目标目录里 - 路径校验只在调用方做了,Decrypt方法里如果传入的路径有变化会出现校验缺失
修复步骤
- 先修正文件名拼接逻辑,统一用
Path.Combine处理路径拼接,避免分隔符缺失问题 - 给else分支也加上文件名生成逻辑,不要直接用目录路径创建文件
- 可选:在Decrypt方法开头加路径合法性校验
修正后的Decrypt方法代码片段
public static void Decrypt(Stream inputStream, Stream privateKeyStream, string passPhrase, string outputDir) { // 先把参数名改成outputDir,明确是目录,避免语义混淆 if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } // ... 保留原有解密逻辑不变 ... if (message is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData)message; PgpObjectFactory of = null; using (Stream compDataIn = cData.GetDataStream()) { of = new PgpObjectFactory(compDataIn); } message = of.NextPgpObject(); string finalOutputPath; if (message is PgpOnePassSignatureList) { message = of.NextPgpObject(); PgpLiteralData Ld = (PgpLiteralData)message; string fileName; if (!string.IsNullOrEmpty(Ld.FileName)) { fileName = Ld.FileName.EndsWith(".txt") ? Ld.FileName : Ld.FileName + ".txt"; } else { fileName = "test" + DateTime.Now.ToString("yyyyMMddHHmm") + ".txt"; } // 用Path.Combine拼接路径,自动处理分隔符 finalOutputPath = Path.Combine(outputDir, fileName); using (Stream output = File.Create(finalOutputPath)) { Stream unc = Ld.GetInputStream(); Streams.PipeAll(unc, output); } } else { PgpLiteralData Ld = (PgpLiteralData)message; string fileName; // 补上文件名生成逻辑,不要直接用目录路径 if (!string.IsNullOrEmpty(Ld.FileName)) { fileName = Ld.FileName.EndsWith(".txt") ? Ld.FileName : Ld.FileName + ".txt"; } else { fileName = "test" + DateTime.Now.ToString("yyyyMMddHHmm") + ".txt"; } finalOutputPath = Path.Combine(outputDir, fileName); using (Stream output = File.Create(finalOutputPath)) { Stream unc = Ld.GetInputStream(); Streams.PipeAll(unc, output); } } } }
额外排查项
如果修复后还是报错,可以再检查以下两点:
- 程序运行身份是否真的有
D:\Decryption\Output的写入权限:IIS进程要给IIS_IUSRS赋权,控制台/Windows服务要给对应的运行用户赋权 - 解密后的文件名是否包含系统禁止的特殊字符,导致创建文件被拒绝
内容的提问来源于stack exchange,提问作者Jagan Nathan
相关产品推荐
相关产品推荐

