【发布时间】:2016-09-13 14:15:30
【问题描述】:
我们目前有一个在旧 Windows 服务器 (Windows Server 2003) 上运行的作业,由于旧服务器即将停用,因此需要将其移至新服务器。此作业作为 Windows 计划任务运行,该任务以频繁的间隔运行,调用 Perl 脚本,该脚本使用供应商的公钥加密某些文件并将加密的文件上传到供应商的外部 FTP 站点。
我是一名自学成才的程序员/开发人员/工程师,不熟悉 Perl,但我一直负责这一举措。
以下是我为实现这一目标而采取的步骤:
- 安装 Perl(Strawberry Perl 使用来自草莓perl.com 的 Windows 二进制 exe)
- 使用来自 www.gnugp.com 的 exe 安装 GPG
- 将 GPG 可执行文件的路径添加到 Windows 环境变量“PATH”,以便它可以在命令提示符下作为“gpg”运行。
- 使用命令
gpg --import [path to the key file]将供应商的公钥添加到GPG -
增加对导入密钥的信任,防止每次使用命令都被挑战:
gpg –-edit-key [name of Prudential’s key] trust 5 y
然后我使用现有脚本,对用于文件路径等的一些常量进行了一些更改,注释掉了 FTP 文件的命令(因为此时我只是在运行临时测试)和试图运行它来加密一些示例文件。脚本成功运行到完成,但是由于文件被加密的命令的结果,生成了一条友好的错误消息。
这里是发生加密的脚本部分:
sub encrypt_outgoing_files {
# open outgoing decrypted directory
&message(sprintf("CD: %s\n", $out_dec_path), 0);
if (opendir(OUT_DEC_DIR, $out_dec_path)) {
# check for new files
&message("Checking for new files\n", 0);
my $file;
my $new_flag;
my %files_hash;
foreach $file (readdir(OUT_DEC_DIR)) {
if (-f $out_dec_path . $file) {
$files_hash{$file} = (stat($out_dec_path . $file))[9];
}
}
my @files = sort { $files_hash{$a} cmp $files_hash{$b} } keys %files_hash; # sort by mtime
foreach $file (@files) {
if (-f $out_dec_path . $file) {
$new_flag = 1;
# rename and encrypt this file
my $out_file = $file;
$out_file =~ s/\.?[0-9]+$//i; # rename outbound files according to this regex
&message(sprintf("Encrypting: %s (%s)\n", $file, $out_file), 1);
if (!system(sprintf("%s -e \"print('%s')\" | %s --batch --passphrase-fd 0 --output %s --local-user %s --recipient %s --sign --encrypt --cipher-algo %s %s >NUL 2>&1", $perl_path, $pgp_passphrase, $pgp_exe_path, $out_enc_path . $out_file . $pgp_extension, $pgp_sender, $pgp_recipient, $pgp_cipher, $out_dec_path . $file))) {
# archive decrypted original
&message("Archiving decrypted version\n", 0);
rename($out_dec_path . $file, $out_dec_path . $archive_dir . $file);
}
# error encrypting this file
else {
unlink($out_enc_path . $out_file . $pgp_extension); # delete partially encrypted file (just in case)
&message("Error encrypting file (will try again next time around)\n", 1);
}
}
}
# nothing new
if (!defined($new_flag)) {
&message("None found\n", 0);
}
# close directory
closedir(OUT_DEC_DIR);
# clean archive
&message(sprintf("CD: %s\n", $out_dec_path . $archive_dir), 0);
&clean_dir($out_dec_path . $archive_dir, $max_archive_age);
}
# invalid directory
else {
&message(sprintf("Directory not found: %s\n", $out_dec_path), 2);
}
}
对于每个文件,我都会收到“错误加密文件(下次将重试)”消息。
但是,如果我尝试使用命令提示符单独使用 GPG 加密其中一个文件,则该文件已成功加密。
所以,我有三个问题:
- 有谁知道可能导致错误的原因?
- 如何找出错误原因?
- 是否有“更好”的方式来完成这项任务,因为这个脚本最初是在十多年前编写的?该脚本现在将在运行 IIS、Java 和 ColdFusion 的 Windows 2012 虚拟机上运行。
【问题讨论】:
-
你能把
stderr和stdout重定向到某个文件(比如>stdout.log 2>stderr.log然后再检查它们吗? -
另外,我会打印出
sprintf的结果,以确保该行看起来应该是这样。 -
@raina77ow 当我添加
stdout和stderr重定向时,stderr文件为空,stdout显示我通常在命令提示符中看到的内容(“错误加密文件。 ...”)。 -
我的建议是在
sprintf输出中重定向它们,而不是按照您调用脚本的方式。 -
@raina77ow 我想通了。起初我只导出/导入了供应商的公钥。我未能导出/导入我们的私钥并正确信任它。它现在正在工作。没有你的帮助是不可能的。谢谢!
标签: windows perl encryption gnupg pgp