如何在 Linux 中解密文件中的单个加密字段(openssl、rsa 密钥)

如何在 Linux 中解密文件中的单个加密字段(openssl、rsa 密钥)

我有一个每天在 Linux 上收到的 csv 文件。文件本身并未整体加密,但其中一个字段已加密,因此它看起来像这样:

数据,数据,数据,加密数据、数据等

我有一个用于解密的 RSA 密钥,现在我正在逐行解析文件,剪切加密字段,使用 openssl 解密,然后将其放回行中,如下所示:

      ###cut out the encrypted field into a variable
    INFIELD=`echo $DATALINE | cut -d"," -f10`

      ###decrypt the field into another variable
    OUTFIELD=`echo $INFIELD | base64 --decode | openssl rsautl -inkey $SCRIPTFILES/MyKey.rsa -decrypt`

      ###swap the decrypted value into the original line and append to a temp file
    echo $DATALINE | awk -v outfield=$OUTFIELD '{$10 = outfield;print}' FS=, OFS=, >> $DATAPATH/$TEMPFILE

这是可行的,但是令人惊奇的是很慢……处理 600,000 行数据需要 4-5 个小时。有没有更快的方法?

答案1

可能可以猜想,为每一行生成 6-7 个全新的进程是最慢的部分,甚至比实际的 RSA 计算还要慢。请注意,每个实例` `也是一个子进程(即使它仍然在 shell 内部,并且不像执行完全外部的工具那样繁重),并且每个echo | ...都是另一个子进程。(据我所知,最近的 Melt/Spectre 缓解措施使这种情况比本来的情况更糟糕。)

因此,更快的方法是使用其他可以执行解密、解码和其他所有操作的语言编写脚本进程中. (即几乎任何不是“shell”并且不依赖于从 /usr/bin 调用工具的语言。)

例如,Python 有“Cryptodome”和“cryptography”模块,Perl 有“CryptX”,而 Ruby 则有“OpenSSL”模块。(其他语言也可用。)当然,几乎所有语言都可以拆分逗号分隔的行并解码 Base64,而无需任何外部帮助。


我目前不知道 OpenSSL 的 rsautl 使用什么具体格式以及如何将其输入到 Cryptodome 库中,但总体思路是:

require 'base64'
require 'openssl'

pkey = OpenSSL::PKey::RSA.new(File.read("MyKey.rsa"))

while line = STDIN.gets()
    fields = line.chomp.split(",")
    fields[9] = Base64.decode64(fields[9])
    fields[9] = pkey.private_decrypt(fields[9])
    puts fields.join(",")
end

相关内容