如何在 Openssl 中生成十六进制输出?

Posted

技术标签:

【中文标题】如何在 Openssl 中生成十六进制输出?【英文标题】:How to generate the output in hexadecimal in Openssl? 【发布时间】:2016-10-31 03:51:32 【问题描述】:

最后我可以通过使用“-a”开关获得base64格式的输出;我可以使用任何十六进制开关吗?

echo '0: 63616e746765747468697332776f726b' | xxd -r | openssl enc -aes-128-ecb -a -K 00000000000000000000000000000000

如果我运行该代码,我会得到这个:

N2+bVLU8fIS7ucFW1Qr/xwFD22PuZrDN/59pkXaAFR4=

...不知何故这也是错误的,因为它应该只是这样:

N2+bVLU8fIS7ucFW1Qr/xw==

无论如何,我只需要能够想出这个输出:

376f 9b54 b53c 7c84 bbb9 c156 d50a ffc7

【问题讨论】:

Stack Overflow 是一个编程和开发问题的网站。这个问题似乎离题了,因为它与编程或开发无关。请参阅帮助中心的What topics can I ask about here。也许Super User 或Unix & Linux Stack Exchange 会是一个更好的提问地方。另见Where do I post questions about Dev Ops?。 @jww 我现在正在编程,这与我正在做的事情完全相关。 Shell 脚本仍然是代码。 Super User 的 mod 可能会将其踢回 SO 或要求 OP 将其重新发布到 Security Stack Exchange 上。我们其他人只是在努力完成工作。 @Alex - 如果您有问题,请随时提问。我们将根据其本身的优点来判断它。 【参考方案1】:

第一季度。不,openssl enc 不能以十六进制输出,只能输出二进制/原始或 base64。但是您显然有xxd 可用,其主要目的是将其转换为十六进制,以便将其输入,然后cut -c10-50 删除最左边的地址和最右边的可打印ASCII 部分以获得您显示的确切格式xxxx xxxx etc;或者xxd -p 'plain' xxxxxxxxod -An -tx1 一步完成xx xx xx xx etc

第二季度。您正在获得(base64 编码)两个密文块,因为带有非流密码的enc 默认为 PKCS#5 填充,而您的明文恰好是一个块(AES 为 16 个字节)。 添加 -nopad 以获得您要求的输出。


由于您似乎无法将在不同时间给出的两个概念结合起来,这里是按顺序排列在一个地方的全部内容

问题:您有十六进制输入并希望以十六进制输出,但openssl enc 以二进制(不是十六进制)输入并以二进制或 base64(但不是十六进制)生成输出。

推论:您必须将输入从十六进制转换为二进制。您还必须将输出从二进制转换为十六进制。尽管它们都包含“十六进制”和“二进制”这两个词,但它们是不同的东西。

第1步:将输入从十六进制转换为二进制,因为您有十六进制并且需要enc的二进制输入

 echo 0: 63616e746765747468697332776f726b | xxd -r 

第 2 步:从二进制到二进制进行加密(无填充)

 openssl enc -aes-128-ecb -nopad -K 00000000000000000000000000000000 

省略步骤:不要使用-a 转换为base64。 你不想要 base64。

第 3 步:将二进制转换为十六进制,因为您有二进制但想要十六进制

xxd -p

TOTAL(使用 $ 的最小 shell 提示符,您的可能不同):

$ echo 0: 63616e746765747468697332776f726b | xxd -r \
| openssl enc -aes-128-ecb -nopad -K 00000000000000000000000000000000 | xxd -p
376f9b54b53c7c84bbb9c156d50affc7
$

这是您要求的结果,除了没有空格,您后来说您不需要。

如果您确实想要间距使用 xxd 而不使用 -p 并添加 cut,就像我最初所说的那样:

$ echo 0: 63616e746765747468697332776f726b | xxd -r \
| openssl enc -aes-128-ecb -nopad -K 00000000000000000000000000000000 | xxd | cut -c10-50
376f 9b54 b53c 7c84 bbb9 c156 d50a ffc7
$

【讨论】:

“-nopad”添加效果很好,但我仍然不太清楚 Q1。 阅读xxd 的手册页第一句:默认情况下(没有选项)xxd 转换为十六进制。只有使用-r(反向)选项,它才会将十六进制转换回二进制/原始。所以省略-r。默认格式按照您所说的将xxxx xxxx xxxx 中的2 字节组中的数据,加上地址和可打印的ASCII(我的cut 删除);如果您对连续的xxxxxxxxxxxx 感到满意,您可以单独使用xxd -p(不使用cut)。 我真的不在乎空间,只是为了表示对称。所以你说我可以转换这个命令:echo "376f9b54b53c7c84bbb9c156d50affc7" | xxd -p -r | base64 以十六进制显示输出??? @cronos 这对于 cmets 来说太长了;查看编辑后的答案 @quapka:xxd 的默认输出格式是地址形式中的一系列行:byte_pairs_in_hex... bytes_as_ASCII...(如我的第一段所述,并在程序的手册页),因此这也是xxd -r 的默认输入 格式,因为xxd -r 的目的是“反转”xxd。第一行数据(这里是only行)的地址为零,0:是最简单的可接受的零后跟冒号的表示; 00000000: 也可以。

以上是关于如何在 Openssl 中生成十六进制输出?的主要内容,如果未能解决你的问题,请参考以下文章

如何从字节中生成十六进制数?

在 Java ME/J2ME 中生成随机十六进制字符串(长度为 50)

c语言中如何将十六进制转换成2个字节输出

C++中十六进制的07,怎么转换成二进制,并且输出时要把前面的几个0也输出,而不是只输出111?

如何用JAVA语言将十六进制数转换成二进制数,并输出

C语言 将99(十进制)转为0x99(十六进制)并输出?