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

如何使用openssl命令行工具解密Perl Crypt::DES加密的密文

如何用OpenSSL命令行解密Perl Crypt::DES加密的密文?

问题背景

我需要使用命令行工具openssl解密由Perl模块Crypt::CBC(基于DES)加密的密文。

加密用的Perl脚本

#!/usr/bin/perl -w
use strict;
use 5.010;
use Getopt::Long qw(:config no_ignore_case);
use Crypt::CBC;
### initialization
&GetOptions("mode=s" => \(my $mode = ''));
my $secret = q/;[qO7e<_sZmR8Krhf>}]mRY`y)BI8"WEF*2nmL^o'WMKA=uEt1/;
my $key = pack('H*', $secret);
open(my $fh, '>', 'key.bin');
$fh->print($key);
$fh->close();
my $cipher = Crypt::CBC->new(
    -key => $key, -cipher => 'DES'
);
### read file
my $filename = shift @ARGV;
open($fh, '<', $filename) or die "$!";
my $cchRead = read($fh, my $buffer, -s $fh);
close($fh);
die "$!" unless defined($cchRead);
### encrypt
if ($mode eq 'encrypt') {
    print $cipher->encrypt($buffer);
}
### decrypt
else {
    print $cipher->decrypt($buffer);
}

脚本使用方式

$ ./cipher.pl --mode=encrypt foo.txt > foo.encrypted # 加密明文
$ ./cipher.pl --mode=decrypt foo.encrypted # 解密密文

我尝试了以下OpenSSL命令,但均未成功:

$ openssl enc -des          -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-cbc      -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-cfb      -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-cfb1     -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-cfb8     -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ecb      -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ede      -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ede-cbc  -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ede-cfb  -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ede-ofb  -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ede3     -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ede3-cbc -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ede3-cfb -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ede3-ofb -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des-ofb      -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -des3         -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -desx         -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'
$ openssl enc -desx-cbc     -salt -pbkdf2 -pass file:key.bin -d -in 'foo.encrypted'

解决方案

失败原因分析

你之前的命令存在三个核心错误:

  1. 多余的密钥推导参数:脚本直接使用pack('H*', $secret)生成的原始密钥,没有通过盐和PBKDF2推导密钥,-salt和-pbkdf2选项完全没必要,反而会导致OpenSSL错误处理密钥。
  2. 未指定正确的IV:Crypt::CBC默认会生成随机8字节IV(DES块大小),并将其前缀在密文头部,OpenSSL不会自动识别这个IV,必须手动提取并指定。
  3. 模式选择错误:Crypt::CBC默认使用CBC模式,只有-des-cbc是正确的加密模式选项,其他模式无法匹配加密逻辑。

解密步骤

方式一:分步操作(生成中间文件)

  1. 从密文中提取前8字节的IV:
dd if=foo.encrypted bs=1 count=8 of=iv.bin
  1. 提取去除IV后的纯密文:
dd if=foo.encrypted bs=1 skip=8 of=ciphertext.bin
  1. 执行OpenSSL解密命令:
openssl enc -des-cbc -d -in ciphertext.bin -iv "$(cat iv.bin | xxd -p)" -K "$(cat key.bin | xxd -p)"

方式二:单命令直接解密(无中间文件)

合并提取IV和密文的操作,一步完成解密:

openssl enc -des-cbc -d -in <(dd if=foo.encrypted bs=1 skip=8 2>/dev/null) -iv "$(dd if=foo.encrypted bs=1 count=8 2>/dev/null | xxd -p)" -K "$(cat key.bin | xxd -p)"

参数说明

  • xxd -p:将二进制的密钥和IV转换为十六进制字符串,符合OpenSSL-K(密钥)和-iv(初始化向量)参数的格式要求。
  • Crypt::CBC默认使用PKCS#5填充,和OpenSSLenc命令的默认填充规则兼容,无需额外指定填充方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:55:13