我有一个Python脚本可以正常工作。它能够解码/解密提供的pwd,并对其进行编码/加密,如下所示:
#!/usr/bin/python
from Crypto.Cipher import DES3
import base64
secret = base64.decodestring('tcxpLw1PsMR0CtXt/HfbIZomvJtDyE6h1Gl4vblX2W4=')
key = secret[:24]
iv = secret[24:]
# Encoded Encrypted password
EEpwd = '4TOHTKsvihUXuUd9M3TpoA=='
print "Encoded Encrypted Password : ",EEpwd
# Decoded Encrypted password
DEpwd = base64.decodestring(EEpwd)
# Decoded Decrypted password
DDpwd = DES3.new(key, DES3.MODE_CBC, iv).decrypt(DEpwd)
print "Decoded (Decrypted ( PWD ) ) : ",DDpwd
# New Decoded Encrypted password
NewDEpwd = DES3.new(key, DES3.MODE_CBC, iv).encrypt(DDpwd)
# New Encoded Encrypted password
NewEEpwd = base64.b64encode(NewDEpwd)
print "New Encoded (Encrypted (",DDpwd,") ) : ",NewEEpwd
...这给了我以下输出:
Encoded Encrypted Password : 4TOHTKsvihUXuUd9M3TpoA==
Decoded (Decrypted ( PWD ) ) : MYweakPW
New Encoded (Encrypted ( MYweakPW ) ) : 4TOHTKsvihUXuUd9M3TpoA==
现在我必须将此脚本迁移到Perl,所以我做了:
#!/usr/bin/perl
use MIME::Base64;
use Crypt::CBC;
$secret = decode_base64('tcxpLw1PsMR0CtXt/HfbIZomvJtDyE6h1Gl4vblX2W4=');
$key = substr($secret,0,24);
$iv = substr($secret,24);
$cipher = Crypt::CBC->new(
-cipher => 'DES_EDE3',
-key => $key,
-iv => $iv,
-header => 'none',
-padding => 'null',
-literal_key => 1
);
# Encoded Encrypted password
$EEpwd = '4TOHTKsvihUXuUd9M3TpoA==';
print "Encoded Encrypted Password : ". $EEpwd ."\n";
# Decoded Encrypted password
$DEpwd = decode_base64($EEpwd);
# Decoded Decrypted password
$DDpwd = $cipher->decrypt($DEpwd);
print "Decoded (Decrypted ( PWD ) ) : $DDpwd \n";
# New Decoded Encrypted password
$NewDEpwd = $cipher->encrypt($DDpwd);
# New Encoded Encrypted password
$NewEEpwd = encode_base64($NewDEpwd);
print "New Encoded (Encrypted ($DDpwd) ) : $NewEEpwd \n";
...但这回到我身边:
Encoded Encrypted Password : 4TOHTKsvihUXuUd9M3TpoA==
Decoded (Decrypted ( PWD ) ) : MYweakPW
New Encoded (Encrypted (MYweakPW) ) : 4TOHTKsvihU=
问题:为什么当我在Perl中加密/编码密码时,它返回一个缩短的字符串?那匹配缺少什么?
此致 RZ
修改
由于我正在更改已接受的答案,请让我澄清此代码用法的某些方面,以证明某些选择的合理性。 当然这不是整个脚本。我已经删除了尽可能多的私人信息,以及已经工作的其他脚本,隔离了需要注意的代码段。 当在远程服务器上更改密码时,脚本的整体意图是管理在其他一些脚本/应用程序中使用的密码。
这段特殊的代码用于处理Remmina在保存的会话中存储的密码。不幸的是,Remmina没有提供一个集中的方法来替换保存的密码,所以在我的情况下,每次我在Windows域更改密码时,我所有的Remmina保存的会话都会过时(我有几十个!)
Remmina存储密码的方式是:
在$HOME/.remmina/remmina.pref
,有一行包含secret=*
,已编码,包含DES3 key
和iv
在每个会话文件中,名为$HOME/.remmina/*.remmina
,其中包含password=*
一行,其中包含您的密码,已编码和加密
那就是说,如果原始的加密/编码密码是正确或错误生成的话是无关紧要的......这就是Remmina的做法,我必须处理它: - /
根据命令行中提供的参数,脚本应该能够从*.remmina
文件中检索存储的密码,或者获取一个新的密码并将其替换为*.remmina
个文件,所以这一点@ jm666在他的EDIT2上提出的非常相关,因为当我从命令行获得一个新密码时,它不会以任何方式填充。
对于我的特定场景,我知道密码永远不会短于8个字节,但可以更长,而不是8的倍数,所以我用新的不同密码测试了这个,并意识到要加密密码Remmina,恰当的是padding = 'null'
null
字符,以强制填充添加额外的null
字符答案 0 :(得分:3)
您选择的填充选项似乎与Python加密库使用的填充选项不同。
我发现通过将-padding选项更改为'space',重新加密的密码与原始密码相同。
答案 1 :(得分:2)
您使用padding=>'null'
询问了perl。只需更改:
$cipher = Crypt::CBC->new(
-cipher => 'DES_EDE3',
-key => $key,
-iv => $iv,
-header => 'none',
-padding => 'null',
-literal_key => 1
);
到-padding => 'none',
并获得与python相同的结果。
注意:上面给出了想要的输出,但它是错误答案,以及@ harmic的答案。见下面的EDIT2。
注意,如果你没有输入任何paddig,(因为你没有在你的python代码中使用任何填充),例如。
$cipher = Crypt::CBC->new(
-cipher => 'DES_EDE3',
-key => $key,
-iv => $iv,
-header => 'none',
#-padding => 'null', # <- commented out
-literal_key => 1
);
perl将使用standard
中定义的PKCS#5
填充,例如padds的数字等于缺少填充字节。例如如果缺少2个字节,填充将为0x02 0x02
如果缺少3个字节,则填充将为0x03 0x03 0x03
。 (因此将产生不同的结果,如没有定义填充的python)
2.31 Tue Oct 30 07:03:40 EDT 2012 - Fixes to regular expressions to avoid rare failures to correctly strip padding in decoded messages. - Add padding type = "none". - Both fixes contributed by Bas van Sisseren.
填充none
支持近两年。 :)
使用none
或space
完全不正确,因为:
您永远无法正确获取原始4TOHTKsvihUXuUd9M3TpoA==
编码字符串 。
尝试直接输入密码MYweakPW
进行加密和编码。
无论使用哪种填充,您永远不会获得原始填充
4TOHTKsvihUXuUd9M3TpoA==
字符串。
您将获得下一个(取决于使用的填充):
Padding: standard 4TOHTKsvihW3UDR8tqmBIg==
Padding: space 4TOHTKsvihU=
Padding: oneandzeroes 4TOHTKsvihUndO+JKCfmog==
Padding: rijndael_compat 4TOHTKsvihU=
Padding: null 4TOHTKsvihU=
Padding: none 4TOHTKsvihU=
明文密码MYweakPW
hexdump:
4d597765616b5057
在decode -> decrypt
获得后(取决于使用的填充方法:)
4d597765616b50570000000000000000
#or
4d597765616b5057
当尝试再次加密时,加密算法再次添加新的填充(或不 - 取决于使用的方法)到字符串。
整个可以在以下脚本中看到(主要是你的,只使用十六进制输出):
use strict;
use warnings;
use MIME::Base64;
use Crypt::CBC;
my $secret = decode_base64('tcxpLw1PsMR0CtXt/HfbIZomvJtDyE6h1Gl4vblX2W4=');
my $iv = substr($secret,24);
my $key = substr($secret,0,24);
for my $padd ( qw(standard space oneandzeroes rijndael_compat null none)) {
my $c = Crypt::CBC->new( -cipher=>'DES_EDE3', -key=>$key, -iv=>$iv,
-header=>'none', -literal_key=>1,
-padding=>$padd
);
print "== Padding: $padd=\n";
display($c);
}
sub display {
my $cipher = shift;
my $EEpwd = '4TOHTKsvihUXuUd9M3TpoA==';
p("Original (encrypted & encoded)", $EEpwd);
my $DEpwd = decode_base64($EEpwd);
ph("Original (decoded still encrypted)", $DEpwd);
my $DDpwd = $cipher->decrypt($DEpwd);
ph("Original plaintext", $DDpwd);
my $NewDEpwd = $cipher->encrypt($DDpwd);
ph("New from orig (encrypted)", $NewDEpwd);
my $NewEEpwd = encode_base64($NewDEpwd);
p( "New from orig (encrypted+encoded)", $NewEEpwd);
my $asc = "MYweakPW";
ph("String $asc", $asc);
my $m1 = $cipher->encrypt($asc);
ph("String (encrypted)", $m1);
p("String (encrypted,encoded)", encode_base64($m1));
}
sub ph { p($_[0] . " hex:", unpack('H*',$_[1]) ) }
sub p { printf "%40.40s %s\n", @_; }
输出,根据使用的填充,比较你在解密/加密后得到的hexdump。 (“oroginal”表示从原始base64编码中获得的字符串,“String”表示从直接输入的字符串MYweakPW
获得的值。
== Padding: standard=
Original (encrypted & encoded) 4TOHTKsvihUXuUd9M3TpoA==
Original (decoded still encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
Original plaintext hex: 4d597765616b50570000000000000000
New from orig (encrypted) hex: e133874cab2f8a1517b9477d3374e9a0a26625e0d2ebb3d4
New from orig (encrypted+encoded) 4TOHTKsvihUXuUd9M3TpoKJmJeDS67PU
String MYweakPW hex: 4d597765616b5057
String (encrypted) hex: e133874cab2f8a15b750347cb6a98122
String (encrypted,encoded) 4TOHTKsvihW3UDR8tqmBIg==
== Padding: space=
Original (encrypted & encoded) 4TOHTKsvihUXuUd9M3TpoA==
Original (decoded still encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
Original plaintext hex: 4d597765616b50570000000000000000
New from orig (encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
New from orig (encrypted+encoded) 4TOHTKsvihUXuUd9M3TpoA==
String MYweakPW hex: 4d597765616b5057
String (encrypted) hex: e133874cab2f8a15
String (encrypted,encoded) 4TOHTKsvihU=
== Padding: oneandzeroes=
Original (encrypted & encoded) 4TOHTKsvihUXuUd9M3TpoA==
Original (decoded still encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
Original plaintext hex: 4d597765616b50570000000000000000
New from orig (encrypted) hex: e133874cab2f8a1517b9477d3374e9a0854bea98199fa99e
New from orig (encrypted+encoded) 4TOHTKsvihUXuUd9M3TpoIVL6pgZn6me
String MYweakPW hex: 4d597765616b5057
String (encrypted) hex: e133874cab2f8a152774ef892827e6a2
String (encrypted,encoded) 4TOHTKsvihUndO+JKCfmog==
== Padding: rijndael_compat=
Original (encrypted & encoded) 4TOHTKsvihUXuUd9M3TpoA==
Original (decoded still encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
Original plaintext hex: 4d597765616b50570000000000000000
New from orig (encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
New from orig (encrypted+encoded) 4TOHTKsvihUXuUd9M3TpoA==
String MYweakPW hex: 4d597765616b5057
String (encrypted) hex: e133874cab2f8a15
String (encrypted,encoded) 4TOHTKsvihU=
== Padding: null=
Original (encrypted & encoded) 4TOHTKsvihUXuUd9M3TpoA==
Original (decoded still encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
Original plaintext hex: 4d597765616b5057
New from orig (encrypted) hex: e133874cab2f8a15
New from orig (encrypted+encoded) 4TOHTKsvihU=
String MYweakPW hex: 4d597765616b5057
String (encrypted) hex: e133874cab2f8a15
String (encrypted,encoded) 4TOHTKsvihU=
== Padding: none=
Original (encrypted & encoded) 4TOHTKsvihUXuUd9M3TpoA==
Original (decoded still encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
Original plaintext hex: 4d597765616b50570000000000000000
New from orig (encrypted) hex: e133874cab2f8a1517b9477d3374e9a0
New from orig (encrypted+encoded) 4TOHTKsvihUXuUd9M3TpoA==
String MYweakPW hex: 4d597765616b5057
String (encrypted) hex: e133874cab2f8a15
String (encrypted,encoded) 4TOHTKsvihU=
结果:
MYweakPW
的4TOHTKsvihUXuUd9M3TpoA==
是不正确地创建的(或故意在MYweakPW
中添加了8个空字符,这些字符已经是8字节填充的。)weak
创建base64编码的字符串,您将看到它是如何填充的。