用法:
$ echo abcdef >file
$ crypt genkey >key
$ crypt encrypt --key "$(cat key)" file >file.aes
$ crypt decrypt --key "$(cat key)" file.aes
abcdef
crypt
使用AES適當填充,醃製和鏈接:
#!/usr/bin/perl
use strict;
use warnings;
use feature qw(say);
use Crypt::CBC qw();
use File::Basename qw(basename);
use Getopt::Long qw();
use constant KEY_LENGTH => 32;
sub random_bytes {
my $n = shift;
open(my $fh, '<:raw', '/dev/urandom')
or die("Can't generate random bytes: Can't open /dev/urandom: $!\n");
read($fh, my $buf, $n)
or die("Can't generate random bytes: Error reading from /dev/urandom: $!\n");
close($fh)
or die("Can't generate random bytes: Error reading from /dev/urandom: $!\n");
length($buf) == $n
or die("Internal error");
return $buf;
}
sub random_bytes_hex {
my $n = shift;
return unpack('H*', random_bytes($n));
}
# $key_hex = generate_aes_key_hex();
sub generate_aes_key_hex {
return random_bytes_hex(KEY_LENGTH);
}
# my $ciphertext_bin = aes_encrypt($key_bin_or_hex, $plaintext_bin);
sub aes_encrypt {
my $key = shift; # 32 random bytes, or 64 random hex characters.
our $plaintext; local *plaintext = \(shift); # Bytes (e.g. UTF-8) to encrypt.
if (length($key) == 2*KEY_LENGTH && $key =~ /^[0-9a-fA-F]*\z/) {
$key = pack('H*', $key);
}
length($key) == KEY_LENGTH
or die("Invalid key\n");
utf8::downgrade($plaintext, 1)
or die("Plaintext contains non-bytes\n");
my $cipher = Crypt::CBC->new(
-cipher => 'Rijndael',
-key => $key,
-header => 'salt',
);
return $cipher->encrypt($plaintext);
}
# my $plaintext_bin = aes_decrypt($key_bin_or_hex, $ciphertext_bin);
sub aes_decrypt {
my $key = shift; # 32 random bytes, or 64 random hex characters.
our $ciphertext; local *ciphertext = \(shift); # Bytes to decrypt.
if (length($key) == 2*KEY_LENGTH && $key =~ /^[0-9a-fA-F]*\z/) {
$key = pack('H*', $key);
}
length($key) == KEY_LENGTH
or die("Invalid key\n");
utf8::downgrade($ciphertext, 1)
or die("Ciphertext contains non-bytes\n");
my $cipher = Crypt::CBC->new(
-cipher => 'Rijndael',
-key => $key,
-header => 'salt',
);
return $cipher->decrypt($ciphertext);
}
sub genkey {
say generate_aes_key_hex();
}
sub encrypt {
my $key_hex = shift;
local $/;
my $plaintext;
while (my $file = <>) {
$plaintext .= $file;
}
say aes_encrypt($key_hex, $plaintext);
}
sub decrypt {
my $key_hex = shift;
local $/;
my $ciphertext;
while (my $file = <>) {
$ciphertext .= $file;
}
print aes_decrypt($key_hex, $ciphertext);
}
sub usage {
my $prog = basename($0);
if (my ($msg) = @_) {
chomp($msg);
warn("$msg\n");
}
warn("Use $prog --help for more information\n");
exit(1);
}
sub help {
my $prog = basename($0);
print("usage: $prog [options] genkey [genkey_options] [--]\n");
print(" $prog [options] encrypt [encrypt_options] [--] [file]\n");
print(" $prog [options] decrypt [decrypt_options] [--] [file]\n");
print(" $prog --help\n");
print("\n");
print(" genkey: Generate a key. It's output to stdout.\n");
print("\n");
print(" encrypt: Encrypts the contents of the named file or stdin.\n");
print(" The encrypted contents are output to stdout\n");
print("\n");
print(" decrypt: Decrypt the contents of the named file or stdin.\n");
print(" The decrypted contents are output to stdout\n");
print("\n");
print("Global options:\n");
print(" [none at this time]\n");
print("\n");
print("\"genkey\" options:\n");
print(" [none at this time]\n");
print("\n");
print("\"encrypt\" options:\n");
print(" --key key_hex (Required)\n");
print("\n");
print("\"decrypt\" options:\n");
print(" --key key_hex (Required)\n");
exit(0);
}
{
Getopt::Long::Configure(qw(posix_default no_ignore_case));
Getopt::Long::GetOptions(
'help|h|?' => \&help,
)
or usage();
defined(my $op = shift(@ARGV))
or usage("Invalid number of arguments");
if ($op eq 'genkey') {
my $key;
Getopt::Long::GetOptions(
)
or usage();
@ARGV == 0
or usage("Invalid number of arguments");
genkey();
}
elsif ($op eq 'encrypt') {
my $key;
Getopt::Long::GetOptions(
'key|k=s' => \$key,
)
or usage();
defined($key)
or usage("Key required");
chomp($key);
length($key) == 2*KEY_LENGTH && $key =~ /^[0-9a-fA-F]*\z/
or usage("Invalid key");
encrypt($key);
}
elsif ($op eq 'decrypt') {
my $key;
Getopt::Long::GetOptions(
'key|k=s' => \$key,
)
or usage();
defined($key)
or usage("Key required");
length($key) == 2*KEY_LENGTH && $key =~ /^[0-9a-fA-F]*\z/
or usage("Invalid key");
decrypt($key);
}
else {
usage("Invalid operation");
}
}
你要加密(這意味着你必須存儲鍵)或者只是模糊(你不需要一個密鑰,只需一個解碼器)? – ikegami
@ikegami是的,這是更正確的術語混淆 - 這正是我的意圖。謝謝。 – Ahdee
然後安裝'rot13',或者寫下你自己的:'perl -e'my%map; @map {「a」..「z」,「A」..「Z」} =(「n」..「z」,「a」..「m」,「N」..「Z」, 「上午」);打印s /([a-zA-Z])/ $ map {$ 1}/rg while <>;'' – ikegami