将 MAC 地址替换为 UUID

将 MAC 地址替换为 UUID

我正在寻找一种方法,在使用日志文件向客户呈现数据之前,每次出现在日志文件中时都屏蔽客户端 MAC 地址(GDPR 规则)。

我可以使用正则表达式识别 MAC 字符串,但不确定最好的屏蔽方法是什么,因为 MD5 似乎不建议使用,因为它几乎是透明的!

我需要给定的 MAC 始终返回相同的掩码/uuid,因为 MAC 会在不同的时间进入,并且我需要在给定的 MAC 通过系统时跟踪它。

使用的正则表达式是 (?<=clientMac":\s")[A-Z0-9]{12}

理想情况下,我想使用一些简单的东西来sed进行替换,但我承认这可能是不可能的。

答案1

根据评论中的要求,这里是一个如何使用 执行此类替换的示例sed。您使用了 /linux 标签,因此使用 GNUsed及其e标志作为s命令应该是安全的:

sed -E 'h;s/.*clientMac":\s"([A-Z0-9]{12}).*/echo secretKey\1|md5sum/e;T
  G;s/(.*)\s*-\n(.*clientMac":\s")[A-Z0-9]{12}(.*)/\2\1\3/' logfile

解释:

  • h命令将行保存到保留空间,因此我们可以在弄乱行后恢复它 (-;
  • s/.*clientMac":\s"([A-Z0-9]{12}).*/echo secretKey\1|md5sum/e匹配整行,将实际的 MAC 放入()以在替换中重复使用。替换形成要执行的命令:echo将 MCA 与“salt”一起使用并将其通过管道传输到md5sum.该e标志使得sed在 shell 中执行此操作并将结果再次放入缓冲区中
  • T如果没有进行替换,则分支到脚本末尾。这是打印没有未经修改的 MAC 的行。仅当进行替换时才执行以下行
  • G附加保留缓冲区中的原始行,因此现在我们有了md5sum输出、换行符和缓冲区中的原始行
  • s/(.*)\s*-\n(.*clientMac":\s")[A-Z0-9]{12}(.*)/\2\1\3/捕获第一对中的 MD5 ()、第二对中 MAC 之前的行以及第三对中 MAC 之后的其余行,从而\2\1\3用 MD5 替换 MAC

答案2

以下perl脚本使用 Digest::MD5或者Digest::SHA模块使用秘密盐将 MAC 地址转换为哈希值。有关模块的更多详细信息,请参阅模块的手册页。值得注意的是,Digest::SHA 还有多种算法可供选择。

编写代码的目的是让您可以轻松选择不同的哈希算法 - 取消注释一个算法并注释掉其他算法,以选择最适合您的算法。顺便说一句,函数版本的输出_base64比函数短一点,_hex但看起来更像线路噪声。

我简化了您提供的正则表达式(看不到任何向后查找的需要)。您可能需要稍微调整一下才能处理您的输入数据......您没有提供任何示例,所以我只是猜测。

#!/usr/bin/perl

# choose one of the following digest modules:
use Digest::MD5 qw(md5_hex md5_base64);
#use Digest::SHA qw(sha256_hex sha256_base64);

use strict;

my $salt='secret salt phrase';

# store seen MAC addresses in a hash so we only have to calculate the digest
# for them once.  This speed optimisation is only useful if the input file
# is large AND any given MAC address may be seen many times.
my %macs=();

while(<>) {
  if (m/clientMac:\s*([A-Z0-9]{12})/i) {
    my $mac = $1;

    if (!defined($macs{$mac})) {
      # choose one of the following digest conversions:

      #my $uuid = sha256_hex($mac . $salt);
      #my $uuid = sha256_base64($mac . $salt);
      my $uuid = md5_hex($mac . $salt);
      #my $uuid = md5_base64($mac . $salt);

      $macs{$mac} = $uuid;
    };

    s/(clientMac:\s*)$mac/$1$macs{$mac}/gio;
  };
  print;
};

答案3

作为替代方法,有时我使用简单的行号作为混淆值。这使得输出更加紧凑且更具可读性。

此外,awk 当需要对文本文件执行“智能”操作时,它是一个很好的工具,具有比sed.在这种情况下执行的“智能”操作是避免在多次遇到任何一个 MAC 地址时重新执行混淆算法。如果您有数千行引用少量 MAC 地址,这可以大大加快操作速度。

在实践中,考虑以下脚本,它还处理任何一行上可能出现的多个 MAC 地址,识别并替换每个出现的情况,然后在末尾打印映射表:

awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v table='sort -k 1,1n | column -t' -- '
$0 ~ pat {
    for (i=1; i <= NF; i++)
        if (match($i, pat)) {
            if (!($i in cache))
                cache[$i]=NR "." i
            $i = "MAC:" cache[$i]
        }
}
1
END {
    print "---Table: "FILENAME"\nnum MAC" | table
    for (mac in cache)
        print cache[mac], mac | table
}
' file.log

通过额外的编辑步骤,或者只需使参数中的命令字符串-v table=将其输出重定向到文件(如-v table='sort -k 1,1n | column -t > table'.也可以通过删除整个END{ … }块来完全删除它。

作为一种变体,使用真正的加密引擎来计算混淆值,因此最后没有映射表:

awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v crypter='openssl enc -aes-256-cbc -a -pass file:mypassfile' -- '
$0 ~ pat {
    for (i=1; i <= NF; i++)
        if (match($i, pat)) {
            addr = cache[$i]
            if (addr == "") {
                "echo '\''" $i "'\'' | " crypter | getline addr
                cache[$i] = addr
            }
            $i = "MAC:" addr
        }
}
1
' file.log

在这里,我用作openssl加密引擎,选择其aes-256-cbc密码(还有一个 Base64 编码的输出,以便文本友好),并使其从名为 的文件中读取加密秘密mypassfile

使用对称密码(如aes-256-cbc)加密的字符串可以通过知道所使用的秘密( 的内容mypassfile,您想自己保留)来解密,因此它们可以被逆转。此外,由于openssl默认情况下使用随机盐,因此每次运行都会为相同的输入生成不同的值。不使用盐(选项-nosalt)会使openssl每次运行产生相同的值,因此安全性较低,但另一方面会在仍然加密的情况下产生较短的文本。

只要您选择的外部命令可以接受来自 stdin 的输入并将输出打印到 stdout,相同的awk脚本就可以用于其他外部命令,而不是仅仅将参数openssl中的命令替换为。-v crypter=awk

使用 MD5 或 SHA 等算法散列的字符串只是单向的(即它们无法逆转),并且对于相同的输入总是产生相同的值,因此您需要对它们进行“加盐”,以便计算出的值输出中产生的内容不能仅在所有可能的 MAC 地址上进行搜索。您可以添加随机“盐”,如以下稍作修改的脚本所示:

awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v crypter='sha256sum' -- '
$0 ~ pat {
    for (i=1; i <= NF; i++)
        if (match($i, pat)) {
            addr = cache[$i]
            if (addr == "") {
                "(dd if=/dev/random bs=16 count=1 2>/dev/null; echo '\''" $i "'\'') | " crypter | getline addr
                cache[$i] = addr
            }
            $i = "MAC:" addr
        }
}
1
' file.log

后一个脚本使用 16 字节长的(伪)随机值作为“盐”,从而在每次运行相同数据时生成不同的哈希值。

相关内容