如何在C#中实现与OpenSSL一致的字节转字符打印方式?
DES加密结果直接打印字符与OpenSSL输出不一致的问题与解决
问题描述
重写OpenSSL相关算法时,DES-CBC加密功能验证正常(十六进制/Base64输出与OpenSSL完全匹配),但直接将加密字节打印为字符时,输出与OpenSSL不一致。
命令对比
OpenSSL命令及输出:
echo "foo bar" | openssl des-cbc -K "0123456789ABCDEF" -iv "0123456789ABCDEF" -provider legacy -provider default | xxd
00000000: bcbf 295f 49a1 b714 6469 2be2 99c9 0dcb ..)_I...di+.....
自定义程序命令及输出:
echo "foo bar" | ./my_openssl des-cbc -k "0123456789ABCDEF" -v "0123456789ABCDEF" | xxd
00000000: efbf bdef bfbd 295f 49ef bfbd efbf bd14 ......)_I....... 00000010: 6469 2bef bfbd efbf bd0d efbf bd di+..........
当前C#打印代码:
// result 为存储DES-CBC加密结果的byte数组 Console.Write(Encoding.UTF8.GetString(result));
核心原因
加密后的二进制数据并非合法的UTF-8编码,使用Encoding.UTF8.GetString()时,.NET会将无法解析的字节替换为U+FFFD(十六进制EF BF BD),这就是输出差异的来源。
而OpenSSL在默认模式下,直接将原始加密字节写入标准输出,不进行任何编码转换——它输出的是纯二进制数据,而非经过编码的字符。
C#实现方案
要匹配OpenSSL的输出,需直接将字节数组写入标准输出流,跳过字符编码转换:
方法一
using System.IO; // 直接写入标准输出流 Console.OpenStandardOutput().Write(result, 0, result.Length); Console.OpenStandardOutput().Flush();
方法二(更简洁)
// 通过Console.Out的基础流写入 Console.Out.BaseStream.Write(result, 0, result.Length); Console.Out.Flush();
执行上述代码后,输出的二进制字节将与OpenSSL完全一致,再通过xxd查看时就不会出现efbf bd的替换字节。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

