我的代码如下:
$x = "This text needs to be encoded"
$z = [System.Text.Encoding]::Unicode.GetBytes($x)
$y = [System.Convert]::ToBase64String($z)
Write-Host("$y")
以下内容将打印到控制台:
VABoAGkAcwAgAHQAZQB4AHQAIABuAGUAZQBkAHMAIAB0AG8AIABiAGUAIABlAG4AYwBvAGQAZQBkAA==
现在,如果我使用 powershell 来解码这个 b64,如下所示:
$v = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($y))
Write-Host("$v")
它将被正确解码,如下所示:
This text needs to be encoded
但是,如果我将前面提到的 b64 编码字符串放入 CyberChef 并尝试使用“From base64”配方对其进行解码,则解码后的字符串是否会填充如下点:
T.h.i.s. .t.e.x.t. .n.e.e.d.s. .t.o. .b.e. .e.n.c.o.d.e.d.
我的问题是,为什么会发生这种情况?
最佳答案
Santiago Squarzon提供了关键的指针:
CyberChef 的配方最有可能期望的是 Base64 字符串编码基于 UTF-8 的字节。原始字符串的编码。
相比之下, - 名字不好 -
[System.Text.Encoding]::Unicode
编码是UTF-16LE编码,其中字符由(至少)两个字节表示(最低有效字节在前)。- Unicode 代码点小于或等于
0xFF
的字符(255
),其中包括输入字符串中所有字符所属的整个 ASCII 范围,因此有一个NUL
byte (值0x0
)作为其双字节表示的第二个字节;例如,字母T
编码为 UTF-16LE 由两字节序列0x54 0x0
组成,其中0x54
本身代表字母T
在 ASCII 编码中 - 因此也在 UTF-8 中,它是 ASCII 的超集,仅将非-ASCII 字符表示为 < em>多字节序列。 - 因此,两字节序列
0x54 0x0
在 UTF-8 上下文中被解释为两个个字符:字母T
(0x54
) 和NUL
(0x0
)。NUL
本身没有视觉表示(它是不可打印的字符),但常见的惯例是将其可视化为.
,这就是你所看到的。
- Unicode 代码点小于或等于
因此,请按如下方式创建 Base64 编码字符串:
$orig = "This text needs to be encoded"
$base64 =
[System.Convert]::ToBase64String(
[System.Text.Encoding]::UTF8.GetBytes($orig)
)
注意:尽管 [System.Text.Encoding]::UTF8
是 - 至少 .NET 6 - 带有 BOM 的 UTF-8 编码,BOM(幸运的是)没有由 .GetBytes()
添加到输入字符串前面方法。顺便说一句:将此编码更改为完全无 BOM 是 being considered .NET 7 之前的版本。
$base64
然后包含:VGhpcyB0ZXh0IG5lZWRzIHRvIGJlIGVuY29kZWQ=
关于powershell - 为什么使用 PowerShell 以外的其他工具进行解码时,PowerShell 生成的 base64 字符串中包含点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74130308/